smart-koa-router
v1.0.4
Published
All in one router for koa.
Downloads
3
Readme
smart-koa-router
概述
smart-koa-router
是一个复合型的Koa
路由处理模块,支持Restful API、静态文件、文件上传、模板渲染,自动解析body参数,支持允许跨域请求,支持API参数校验和自动生成文档,支持应用启动时拦截等功能。
这是一个与koa-router
在使用方式上接近,但是设计理念完全不同的Koa
路由处理模块:不仅覆盖了web应用需要的所有场景,而且更加灵活方便,在性能上也比koa-router
表现更为优异。
如何使用
Router
是一个class
,且使用了async
和await
,因此需要在node v7.6+
环境中才能使用。
实例化
你可以根据需要多次实例化Router
对象,每个实例化router
对象使用不同的配置。
var Router = require('smart-koa-router');
var router = new Router();
router.get('/index', function(ctx) {
ctx.body = 'Hello world!';
});
所有的配置参数都是可选的,这时会使用默认值或者具体某个路由的设置。
- options.prefix: 路由前缀,可通过
router.prefix()
方法覆盖,默认为/
- options.methods: 支持的methods,默认为['HEAD', 'OPTIONS', 'GET', 'PUT', 'PATCH', 'POST', 'DELETE']
- options.parseBody: 默认情况下,对于
POST
、PUT
和PATCH
请求,会自动解析body,也可以自定义解析body配置- options.allowCross: 是否允许跨域,默认为false,可以简单地设置为true来使用默认配置,也可以自定义跨域配置
- options.staticFile: 默认的静态文件资源配置
- options.uploadFile: 默认的文件上传配置
- options.renderFile: 默认的模板渲染配置
- options.swagger: 默认的Swagger文档配置
- options.validator: 参数校验配置,默认为true,可以简单地设置为false来禁用参数校验
- options.document: swagger文档基础配置,具体可以参考OpenAPI Specification
使用路由
路由的实例化虽然是多次的,但是路由的使用却只需要一次。
var koa = require('koa');
var Router = require('smart-koa-router');
app.use(router.routes());
app.listen(8444, '0.0.0.0', function() {
console.log('http://localhost:8444');
});
API
router.use(methods, path, opts, ...middleware)
定义一个路由拦截行为,统一拦截请求进入时的操作。
router.use(['POST', 'PUT', 'PATCH', 'DELETE'], async function authorizeMiddleware(ctx, next) {
// 所有的增删改操作都要进入权限认证
await next();
});
参数
methods: String|String[],接收的request method,如果省略则接收所有的默认允许的methods
path: String|RegExp,接收的request path,如果省略则等同于'*',如果为字符串则表示支持参数
为了支持swagger的path参数格式,在解析参数时使用了open-path模块来代替
path-to-regexp
opts: 路由配置,与实例化时的参数配置相同,该参数可以省略,也可以写在middleware的后面
middleware: 一个或多个路由处理中间件
router.param([path], param, middleware)
对指定路径参数作统一拦截,属于router.use()方法的语法糖。
router
.param('user', (id, ctx, next) => {
ctx.user = users[id];
if (!ctx.user) return ctx.status = 404;
return next();
})
.get('/users/:user', ctx => {
ctx.body = ctx.user;
})
.get('/users/:user/friends', async (ctx) => {
var friends = await ctx.user.getFriends();
ctx.body = friends;
});
// /users/3 => {"id": 3, "name": "Alex"}
// /users/3/friends => [{"id": 4, "name": "TJ"}]
router.prefix(prefix)
定义路由前缀,在此之后定义的路由,只要path
是以./
开头的,都会自动加上此前缀。
router.any(methods, path, opts, ...middleware)
不同于路由拦截,路由定义最多只会命中一个定义的路由,且后定义的路由将覆盖先定义的路由。
参数
相比于通用配置,多了一个opts.annotations
配置,用于描述该路由和校验请求参数,声明方式请参考operation-object。
另外还有一个opts.routeOptions
配置,供中间件调用。
router.get(path, opts, ...middleware)
定义一个get
请求,同时会定义一个head
请求,如果需要自定义head
请求,只需要手动定义一个head
请求覆盖掉即可。
router.post(path, opts, ...middleware)
定义一个post
请求。
router.put(path, opts, ...middleware)
定义一个put
请求。
router.patch(path, opts, ...middleware)
定义一个patch
请求。
router.delete(path, opts, ...middleware)
定义一个delete
请求。
router.head(path, opts, ...middleware)
定义一个head
请求。
router.options(path, opts, ...middleware)
定义一个options
请求。
router.static(methods, path, opts, ...middleware)
通过定制的koa-send模块,满足提供静态文件服务的需求。
// 单个文件
router.static('/index.html', {
staticFile: {
filename: 'index.html',
root: __dirname
}
});
// 整个目录
router.static('/assets', {
staticFile: {
root: __dirname,
include: /(css|js|html)$/i
}
});
参数
除了methods的默认值为GET外,其余参数无区别。
router.render(methods, path, opts, ...middleware)
用于提供根据模板渲染页面的能力。
router.render(docUrl, {
renderFile: {
template: path.resolve(__dirname, 'swagger-ui/index.ejs'),
data: Object.assign({
home: '/',
title: 'Swagger UI',
pageTitle: 'Swagger',
url: '/api-docs',
auth: null
}, options.swaggerUi)
}
});
参数
除了methods的默认值为GET外,其余参数无区别。
自定义Engine
请参考/src/render/engine/ejs-engine.js。
router.upload(methods, path, opts, ...middleware)
通过定制的busboy模块,满足文件上传的需求。并实现了FileStorage
和MemoryStorage
来接收处理文件,还支持自定义Storage
。
router.upload('./upload', {
uploadFile: {
root: path.resolve(__dirname, 'uploads'),
allowedFileExts: 'js,png'
}
}, async (ctx, next) => {
console.log(ctx.req.body); // 除type=file外的其它fields
console.log(ctx.req.files); // 由Storage返回的文件对象
console.log(ctx.request.body); // 等价于 ctx.req.body
console.log(ctx.request.files); // 等价于 ctx.req.files
ctx.body = '上传成功!';
});
参数
除了methods的默认值为POST外,其余参数无区别。
自定义Storage
请参考/src/upload/storage/file.js。
router.redirect(source, target, code)
路由跳转。
参数
- source: 访问路径
- target: 目标位置
- code: 状态码,默认为301
router.beforeStart(callback)
在服务启动之前的通用拦截操作,此时会执行传入的callback。
参数
- callback: Function,待执行的回调函数,入参为已定义的所有routes对象数组。
ctx
路由在处理过程中会往koa
的ctx
对象上塞入一些变量。
ctx.route
当前命中路由的实例对象。
ctx.router
当前的实例化router对象。
ctx.routeOptions
从路由定义时传入的额外配置参数(opts.routeOptions),主要是为了在拦截阶段可以根据路由定义的不同routeOptions来分别处理。
ctx.params
定义在path上的参数解析之后的对象。
ctx.req.body和ctx.request.body
解析之后得到的body参数。
ctx.req.files和ctx.request.files
解析之后得到的文件上传对象。
ctx.req.formData和ctx.request.formData
解析multipart/form-data
时得到的内容,即body
+ files
。
路由配置
解析body配置
- parseBody.encoding: String,字符编码,默认为'utf8'
- parseBody.jsonLimit: Array,
Content-Type
为application/json
时的body大小,默认不超过2MB- parseBody.formLimit: Array,
Content-Type
为application/x-www-form-urlencoded
时的body大小,默认不超过56KB- parseBody.jsonFormats: Array,
Content-Type
的值,默认为['application/json']- parseBody.formFormats: Array,
Content-Type
的值,默认为['application/x-www-form-urlencoded']- parseBody.onerror: Function,解析错误处理回调函数,传入参数为一个错误对象,
this
将指向Koa
的context
。如果不指定,则将返回400状态。
跨域配置
- allowCross.origin: 设置
Access-Control-Allow-Origin
头,值可以是以下类型: Boolean - 为true
时设置为请求头的Origin
字段,为false
时将禁用跨域。 String - 设置为指定值。例如指定为http://example.com
时,只有从http://example.com
发起的请求才能跨域。 RegExp - 当请求头的Origin
字段匹配时才能跨域。例如指定为/example\.com$/
时,所有以example.com
结尾的网站发过来的跨域请求都将被允许。 Array - 允许列表中的多个网站跨域。 Function - 自定义是否允许跨域。第一个参数为请求头的Origin
字段,第二个参数为一个回调处理函数(回调的第一个参数为err [object],第二个参数为allow [bool])。- allowCross.methods: 设置
Access-Control-Allow-Methods
头,值可以是个数组(如: ['GET', 'PUT', 'POST'])或者以英文逗号分隔的字符串(如: 'GET,PUT,POST')。- allowCross.allowedHeaders: 设置
Access-Control-Allow-Headers
头,值可以是个数组(如: ['Content-Type', 'Authorization'])或者以英文逗号分隔的字符串(如: 'Content-Type,Authorization')。如果未指定该设置,那么将自动使用请求头的Access-Control-Request-Headers
字段。- allowCross.exposedHeaders: 设置
Access-Control-Expose-Headers
头,值可以是个数组(如: ['Content-Range', 'X-Content-Range'])或者以英文逗号分隔的字符串(如: 'Content-Range,X-Content-Range')。- allowCross.credentials: 设置
Access-Control-Allow-Credentials
头,值为true或false(默认为false)。当需要允许跨域传cookie时,需要设置为true。- allowCross.maxAge: String,设置
Access-Control-Max-Age
头。- allowCross.optionsSuccessStatus: String,设置
OPTIONS
请求时返回的状态码,默认为204(No Content)。
静态文件资源配置
- staticFile.maxAge: 设置浏览器最大缓存时间(毫秒),默认为0。
- staticFile.immutable: 设置资源是否不会变更,可以永久缓存,默认为false。
- staticFile.hidden: 设置是否允许输出隐藏文件,默认为false。
- staticFile.root: 设置资源文件所在的根目录,必需指定。
- staticFile.index: 设置目录下的默认页,如果设置该值,则当用户直接访问该目录时,会自动跳转到默认页。
- staticFile.gzip: 设置是否自动使用gzip压缩文件(.gz),默认为true。
- staticFile.brotli: 设置是否自动使用brotli压缩文件(.br),默认为true。
- staticFile.setHeaders: 设置自定义响应头
Cache-Control
或Last-Modified
,该方法接受res, path, stats
三个参数。- staticFile.extensions: Array,设置自动补全的文件扩展名,默认为false。
- staticFile.filename: 设置静态文件对应的文件名,当为目录时不需要指定该配置。
- staticFile.filter: Function,接收请求的filename,返回true时才能访问该静态资源文件,默认无限制。
- staticFile.include: RegExp,限制允许访问的静态资源文件,当设置了
filter
时该选项将被忽略。- staticFile.exclude: RegExp,限制不允许访问的静态资源文件,当设置了
filter
时该选项将被忽略。- staticFile.converter: Function,接收请求的filename,返回对应的本地文件的filename。
- staticFile.mapList: key/value,设置请求的filename到本地文件的映射关系,当设置了
converter
时该选项将被忽略。- staticFile.onerror: Function,错误处理回调函数,传入参数为一个错误对象,
this
将指向Koa
的context
。如果不指定,则将直接抛出该错误。
文件上传配置
- uploadFile.storage: Class,上传文件处理类。当指定了
uploadFile.root
时,将使用FileStorage
保存为本地文件,否则使用MemoryStorage
保存到内存- uploadFile.allowedFileExts: String|Array,允许的上传文件名后缀,默认为*
- uploadFile.allowedFileNames: String|Array,允许的上传文件名(即input的name属性),默认为*
- uploadFile.root: String,文件保存的根目录(绝对路径)
- uploadFile.mode: Number,文件保存目录的权限,默认为0777
- uploadFile.multiple: Boolean,是否允许多文件上传(即input的multiple属性),默认为false
- uploadFile.fieldNameSize: Number,允许的字段名总大小,默认为100B
- uploadFile.fieldValueSize: Number,允许的字段值总大小,默认为1M
- uploadFile.fieldsCount: Number,允许的字段总个数,默认不限制
- uploadFile.fileSize: Number,允许的字段总个数,默认不限制
- uploadFile.fieldsCount: Number,允许的字段总个数,默认不限制
- uploadFile.fieldsCount: Number,允许的字段总个数,默认不限制
- uploadFile.fileSize: Number,允许的单个文件大小(单位为Byte),默认10240(即10MB)
- uploadFile.filesCount Number,允许上传的文件个数,默认不限制
- uploadFile.partsCount Number,允许的字段+文件总个数,默认不限制
- uploadFile.onerror Function,上传出错时的处理方式,如果不指定则将直接返回500状态
模板渲染配置
- renderFile.engine: Class,模板渲染类。默认为ejs
- renderFile.data Object,传入用于模板渲染的额外数据
- renderFile.template String,模板文件的绝对路径
- renderFile.onerror Function,渲染出错时的处理方式,如果不指定则将直接返回500状态
Swagger文档配置
- swagger.docApi: String,api文档接口地址,默认为"/api-docs"
- swagger.docUrl: String,swagger页面地址,默认为"/swagger-ui.html"
- swagger.swaggerUi: Object,swagger-ui的相关配置
- swagger.swaggerUi.home: String,首页地址,默认为"/"
- swagger.swaggerUi.title: String,title标签内容
- swagger.swaggerUi.pageTitle: String,页面上显示的标题内容
- swagger.swaggerUi.url: String,api文档接口地址,默认为"/api-docs"
- swagger.swaggerUi.auth: Object,auth配置
参数校验配置
- validator.onerror Function,校验不匹配时的处理方式,如果不指定则将直接返回400状态
示例
更多使用示例请查看examples目录。