让我们来从新设想一下 koa-router

媒介

koa-router 是现在用的比较多的 Koa 的路由中间件之一,前段时间因为作者没有精神继续保护而将其公然售卖。我们有些项目也用到了这个库,然则现在许多我们想要的特征都没有,比方天生接口文档。自身这个库代码完成还比较简朴,因而综合斟酌盘算重写一个。

项目地点:https://github.com/d-band/koa…

特征:

  • 支撑险些一切的 koa-router 特征
  • 支撑 params 校验
  • params 支撑从 path, header, query, cookie 中猎取
  • 支撑 body parser
  • 支撑 request body 校验
  • 支撑参数范例自动转换
  • 支撑自动天生 OpenAPI

简朴例子:

index.js

import Koa from 'koa';
import Mapper from 'koa-mapper';
import * as service from './service';

const Mapper = new Mapper();

mapper.get('/users/:id/projects', {
  params: {
    id: { type: 'number' },
    status: { type: 'array<string>', in: 'query' },
    token: { type: 'string', in: 'header' }
  }
}, service.getProjects);

mapper.post('/users/:id/projects', {
  params: {
    id: { type: 'number' }
  },
  body: 'Project'
}, service.addProject);

mapper.schema('Project', {
  id: { type: 'number', required: true },
  name: { type: 'string', required: true },
  status: { type: 'array<Status>', required: true }
});

mapper.schema('Status', {
  id: { type: 'integer' },
  name: { type: 'string' }
}, {
  required: ['id', 'name']
});

app.use(mapper.routes());
app.use(mapper.allowedMethods());

app.listen(3000);

// open http://localhost:3000/openapi.json

service.js

export async function getProjects(ctx) {
  const { id, status, token } = ctx.params;

  await checkToken(id, token);

  ctx.body = await Project.findAll({
    where: {
      userId: id,
      status: { $in: status }
    }
  });
}

export async function addProject(ctx) {
  const { body } = ctx.request;

  ctx.body = await Project.create({
    ...body,
    userId: id
  });
}

路由定义:

mapper.get(path, [options], ...middlewares);
mapper.post(path, [options], ...middlewares);
mapper.put(path, [options], ...middlewares);
mapper.del(path, [options], ...middlewares);
...

options 为可选参数,包括:

  • name: 路由称号
  • params: 要求参数定义
  • body: 要求 Body 定义
  • 其他 OpenAPI 中 Operation Object 的参数

options.params 为要求参数定义,如:

params = {
  id: { type: 'number' },
  name: { type: 'string', in: 'query' },
  user: { type: 'User', in: 'query' }
}
  • type: 参数范例,包括基础范例(numberstringintegerdatetimedatetime),数组范例(array<string>),自定义范例(如 User),自定义数组范例(array<User>),多个范例(number|string
  • in: 参数泉源,包括 path,header,query,cookie
  • 其他 OpenAPI 中 Parameter Object 的参数

自定义范例

mapper.define(schemaName, properties, options);
// or
mapper.schema(schemaName, properties, options);

支撑范例组合,如:

mapper.schema('Status', {
  id: { type: 'integer' },
  name: { type: 'string' }
}, {
  required: ['id']
});
mapper.schema('Project', {
  id: { type: 'number', required: true },
  name: { type: 'string', required: true },
  status: { type: 'array<Status>', required: true }
});

支撑继续,如:

mapper.schema('Model', {
  id: { type: 'number' },
  createdAt: { type: 'datetime' },
  updatedAt: { type: 'datetime' }
});
mapper.schema('User: Model', {
  name: { type: 'string' }
});

Body Parser

mapper.post('/users', {
  body: 'User'
}, (ctx) => {
  const { id, name } = ctx.request.body;
});

支撑文件上传,如:

mapper.post('/uploadImage', {
  bodyparser: { multipart: true },
  body: {
    user: { type: 'number' },
    image: { type: 'file' }
  }
}, (ctx) => {
  const { user, image } = ctx.request.body;
});

末端

现在 koa-mapper 刚宣布,测试覆蓋率到达 100%,有哪些有兴致的小伙伴迎接一同保护。

    原文作者:徐振震
    原文地址: https://segmentfault.com/a/1190000018432088
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞