Koa - first experience (write interfaces)

Foreword

  Not the n- ode.js front-end is not a good front-end!

  In recent years node.js is indeed more and more fire, a lot of companies node.js are beginning to have requirements. Although the front end does not have to be back-end, but want to become a good front end, node.js is the only way.

  I am node.js first impression is that it is a back-end language, but the cost will be lower front end up learning better get started. After slowly understand, using node.js write interface is very convenient for front-end, but not limited to write interfaces. In some large companies, node.js is not a prime target for development interface, but is used as an intermediate layer. We all know that division of labor, more professional people to do professional things, work efficiency will be greatly improved. node.js as an intermediate layer, allowing more focus on the back-end interface to write and manage data.

  Imagine, now, because the business logic changes, back-end need to make changes to the data interface, you will spend time? If you would node.js , then you can node.js do data aggregation, data from several interfaces for front-end splicing use without the need for data structure and data contents trouble, and you do not have to worry about efficiency, because node .js inherently asynchronous.

  Including our used some scaffolding tool is also based on node.js environment set up, you can even use node.js to do data mining, it is what we call reptiles, node.js application level as well. These are some of the information I learned.

  Currently node.js more mainstream framework is divided into express, koa, egg. koa as a new generation framework built by the same team of developers express support of ES7 async / await, abandoned callbacks, more natural on the wording. koa did not bind any of the intermediate member, the key point is to provide high-level design "syntactic sugar" in its lower middleware layer, koa volume and therefore smaller. (Middleware koa is a very important presence, I will focus on in the back to learn it)

  Next, I want to start koa approach the pit.

 

koa first experience

hello, soldier!

Create a app.js, command-line execution node app

const Koa = require('koa' );
const app = new Koa();

app.context.msg = 'Hello Koa!' 
app.use(async ctx => {
  ctx.body = ctx.msg;
});

app.listen( 3000);

app.context  add properties and methods to perform context  

app.use  given method to the middleware application

The method receives ctx and next as an argument, ctx  is the execution context, which stores request and response information, there ctx.body, we can return data through it, next as a function call, the next execution right to intermediate piece execution.

Here I first installed a nodemon, because each time a file changes, you need to re-execute the command to update the code, this repetitive work on to module to handle.

By npm i nodemon After installation, command-line execution nodemon App , so when each file changes, nodemon are automatically refreshed.

 

Koa-router route management

To code maintainability, reduce the code amount. Use routing management is particularly important, koa frame has its own corresponding routing management module (koa-router), we can use through npm download.

var Koa = require('koa' );
var Router = require('koa-router' );
 
var app = new Koa();
var router = new Router();
 
router.get( '/', (ctx, next) => {
      ctx.body = 'hello'
});

//使用路由中间件 app .use(router.routes()) .use(router.allowedMethods()); app.listen(
3000 )

Sign routes using routing

allowedMethods 处理的业务是当所有路由中间件执行完成之后,若 ctx.status 为空或者404的时候,丰富 response 对象的 header 头,不加问题也不大,官方例子有加上,所以我这里也加了

这时访问3000端口就可以得到ctx.body 返回的内容

get请求

1. 获取接口query参数

通过查询 ctx.request.query 得到get参数, ctx.request.header 得到请求时的头部信息,ctx.request.method 得到请求方法。这样可以对应的来做一些判断,例如请求的参数是否合法,请求方法是否合法。

router.get( '/get', (ctx, next) => {
      let id = ctx.request.query.id
      ctx.body = {
           id,
           code: 1
      }
});

 

2. 命名路由  获取参数

router.get( '/get/:id', (ctx, next) => {
      let id = ctx.request.params.id
      ctx.body = {
           id,
           code: 1
      }
});

例如请求地址为 /get/123,通过 ctx.request.params 获取参数

这写法让我想起了vue-router,设置params可以说是一样了。

 

post请求

原生获取post请求的参数,需要监听ctx.req的data事件和end事件,分段拼接成完整的字符串,然后还需要切割转码。所以在获取post参数时,我会借助 koa-bodyparser 来减少不必要的操作。

在引入 koa-bodyparser 时,需要注意的是顺序问题,使用 koa-bodyparser 需要放在使用路由之前,这是由于中间件执行顺序的原因(暂且理解为 bodyparser 经过处理,把处理好的值转交到路由)

var bodyParser = require('koa-bodyparser');

app.use(bodyParser());

app
    .use(passport.initialize())
    .use(passport.session())

 

借助中间件koa-bodyparser,访问 ctx.request.body 得到post参数

通过 ctx.set 设置返回头,设置多个时可传入对象

router.post('/post', ctx=>{
   //设置允许跨域
   ctx.set('Access-Control-Allow-Origin','*') ctx.body
= { code:1, postParams:ctx.request.body } })

 

路由模块化管理

试想一下,现在文件中写有多个接口,我们在开发和调试起来都会特别麻烦,浪费时间。为了更好的管理接口,现在需要把接口按照功能抽离出来,封装到一个个的JS文件中,并存放到routes文件夹下。

例如,创建 user.js 来存放用户相关的接口

const Router = require('koa-router')
const route = new Router()
const jwt = require('jsonwebtoken')

route.get('/getToken', async (ctx)=>{
    let {name,id} = ctx.query
    if(!name && !id){
        ctx.body = {
            msg:'不合法',
            code:0
        }
        return
    }
    //生成token
    let token = jwt.sign({name,id},'secret',{ expiresIn: '1h' })
    ctx.body = {
        token: token,
        code:1
    }
})

route.get('/getUser', async ctx=>{
    let id = ctx.query.id
    ctx.body = {
        user:ctx.payload,
        id,
        code:1
    }
})

route.get('/getAllUser', async ctx=>{
    let type = ctx.query.type
    if(type){
        ctx.body = {
            type,
            code:1
        }
    }else{
        ctx.body = {
            msg:'缺少参数type',
            code:0
        }
    }
})

module.exports = route

以上代码,将写好的接口暴露出去,供app.js注册使用

 

app.js代码(部分代码省略)

let urls = fs.readdirSync(__dirname + '/routes')
urls.forEach((element) => {
    //routes里的js接口文件
    let module = require(__dirname + '/routes/' + element)
    //routes里的文件名作为 路由名
    router.use('/' + element.replace('.js', ''), module.routes())
})

//使用路由
app.use(router.routes()).use(router.allowedMethods())

app.listen(3000)

以上代码,我大概讲下流程

1. fs文件模块读取routes文件夹目录内容(获得的是一个文件名的数组)

2. 数组遍历,引入接口文件,将文件名作为路由名,注册使用路由

将 user.js 作为例子,user.js 内有一个 getUser 的接口,我访问的api地址为 /user/getUser

 

头部信息处理

在前后端交互中,头部信息也是很关键的一步,通过对头部信息的配置,可以对请求作出一些限制,或者是一些优化。

这里我会使用 koa2-cors 为例子,来对跨域做cors处理(部分代码省略)。

const cors = require('koa2-cors')

app.use(cors({
    origin: function(ctx) {
      return 'http://127.0.0.1:5500';//cors
    },
    exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
    maxAge: 5,
    credentials: true,
    allowMethods: ['GET', 'POST'],
    allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
}))

app.use(router.routes()).use(router.allowedMethods())

app.listen(3000)

origin : 接受字符串和函数,这里配置的就是允许跨域的域名,如果允许所有域名跨域可传入 *

allowMethods : 允许请求的方式

allowHeaders : 允许接受的头部信息

其他的配置选项可以在npm上查看:https://www.npmjs.com/package/koa2-cors

 

写在最后

本文通过路由中间件简单实现接口,模块化管理接口文件,还对接口进行跨域处理。

主要还是玩模块,通过模块可以组合出适合自己业务的系统。

Guess you like

Origin www.cnblogs.com/chanwahfung/p/11415675.html