npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

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,且使用了asyncawait,因此需要在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: 默认情况下,对于POSTPUTPATCH请求,会自动解析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模块,满足文件上传的需求。并实现了FileStorageMemoryStorage来接收处理文件,还支持自定义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

路由在处理过程中会往koactx对象上塞入一些变量。

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-Typeapplication/json时的body大小,默认不超过2MB
  • parseBody.formLimit: Array,Content-Typeapplication/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将指向Koacontext。如果不指定,则将返回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-ControlLast-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将指向Koacontext。如果不指定,则将直接抛出该错误。

文件上传配置

  • 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目录。