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

ec-router

v1.2.0

Published

一个koa2自动路由中间件,直接根椐请求方法及路径路由到指定的controller。无需人工编写路由表或映射

Downloads

29

Readme

ec-router License

一个简单易用的koa2路由中间件,提供规则路由功能,不再需要复杂无趣的路由文件,路由影射表等。

feature

  1. koa2路由中间件

  2. 根椐请求方法及URI进行自动路由

  3. 控制器钩子,支持before,after,error

  4. 配置文件及控制器热重载

change log

如果你之前使用过ec-router,请注意新版本为了保持router的功能单一性,相对旧版本,作了比较大的简化,修改如下:

  1. 去掉了自动装载数据库进行自动RESTful的功能,如果你需要此功能,请参考本文档后面的使用例子自行实现。

  2. 增加_any控制器,处理无法匹配的的resource

  3. 在hook中增加error方法,处理路由过程抛出的错误

  4. 默认的控制器方法名称由all改为_any

  5. 将resource、resourceId和action注入到 ctx.ecRouter

install

npm install ec-router --save
npm test

也可从 git仓库 中下载源码,放到你项目的node_modules目录

URI格式说明

 http://domain[:port]/[prefix]/[apiver]/path

[prefix] : 表示路径前缀(可为空),可在config中设置

[apiver] : 表示api的版本,在config中设置 apiVer 为true时生效, 版本规则由apiVeRegex定义,默认规则为两位版本号,比如v1.0,v11,v2,11,12.22

path : 为具体资源路径,根椐不同的路由类型有不同

ec-router根椐请求的方法、路径或查询参数,自动分析得出controller(resource)和action,再调用相应的方法来处理。

如果对应的controller没有找到,会在controllers目录查找_any.js来代替(使用者可在此控制器内用_any方法来实现自动处理RESTful请求)

如果对应的action没有找到,则查找_any方法代替。

如果都找不到,则抛出异常,进入_hook的error方法处理(如果有的话)

route type

type=1, RESTful方式

本方式使用RESTful访问,根椐请求方法和请求的资源名称、ID来处理,比如:

GET /res/12    // => controller=res,method=get
POST /User     // => controller=user,method=post
PUT /user/11   // => controller=user,method=put

其中的"res"和"user"表示资源名称

type=2,Path方式

本方式根椐路径匹配控制器和控制器方法, path的格式为: /controller/action

如:

/res/list      // => controller=res, method=list
/user/add      // => controller=user, method=add
/user          // => controller=user, method=any

该方式不区分请求方法,可在实现控制器时根椐需求自行判断

type=3,QueryString方式

本方式使用请求字符串进行路由判断,比如:/apiName?c=controller&a=action,查找controller及action的方式同type=2

(其中c,a为参数名称,可在config中修改)

如:

/index?c=user&a=list  // => controller=uer, method=list 
/index?c=user&a=add   // => controller=user, method=add
/index?c=user&a=      // => controller=user, method=any

此方法同样不区分请求方法,可在实现控制器时根椐需求自行判断

Usage

koa app main

//index.js
const Koa = require('koa')
const app = new Koa()
const ecRouter = require('ec-router')

process.env.NODE_ENV = 'dev' //开启debug log

//加载其它中间件
//如果需要自动RESTful服务,需要使用bodyParser之类的请求内容解释中间件来预处理请求参数
app.use(bodyParser())

//修改ec-router的默认配置
ecRouter.loadConfig(__dirname+'/ec-config.js')
app.use(ecRouter.dispatcher())

//use other middleware

app.listen(3000)

热加载

当在配置文件中设置了hotLoad=true(缺省值)时,ec-router支持配置文件及controller的热加载(hotLoad配置的修改不支持热更新)

如果需要使用热加载,请将配置独立成模块,再使用 ecRouter.loadConfig('./config.js') 代替 ecRouter.setConfig(conf)

controller

ec-router通过dispatch将不同的请求路由到不同的控制器方法,默认地,需要将控制器文件放置在APP根目录下的controllers目录(可在配置中修改)

  1. 控制器文件名、控制器方法、资源名称等大小写敏感

  2. 控制器方法的函数原型是 async (ctx) =>{}

  3. type=1时,使用get,post,put,delete来命名对应的控制器方法,type非1时,可以自行定义(对应path或querystring中的action命称),可以定义_any方法来适配不存在的方法。


// controllers/user.js
module.exports = {
    get : async (ctx) => {
        //ctx.req.resourceId  //effective when type=1,
        //ctx.req.resource
        ctx.body = "get User"
    },
    post: async (ctx) => {
        ctx.body = "post user"
    },
    //当action无法匹配以上方法时,会自动匹配为此方法
    _any: async (ctx) => {
        //other method
    }
}

api version

对于是否应该在URI中添加api的version,不同的人有不同的看法,ec-router建议的方式在你需要版本控制时,在URI中添加。

  1. 配置中设置 apiVer为true
  2. 需在controllers目录下创建版本目录,并将控制文件放到相应的版本目录,如 : 路径/v1/res,会路由到 controllers/v1/res.js。

如果你希望使用Accept的media type或其它header来控制版本,可以在_any控制器的_any方法中,判断并依靠获得的版本号及注入到ctx.ecRouter的resource,action来require相应版本的控制器

通用controller

通用controller需要使用者自行定义并放置在controller目录,该节说明通用控制器的用途及实现方法。

before和after钩子

如果需要在每个控制器方法执行之前或之行都执行一些逻辑,可以使用钩子,方法是:

  1. 在 controllers目录下放置控制器钩子,文件名为 _hook.js
  2. 在_hook.js中实现并导出before或after方法(可同时或单独前后添加钩子),方法原型与普通controller方法一样
module.exports = {
    //do before all controller action
    before : async (ctx) => {
        ctx.set("Access-Control-Allow-Origin", "*") 
        ctx.set("Access-Control-Allow-Headers", "Origin, Content-Type") 
    },

    //do after all controller action
    after: async (ctx) => {
        console.log('controller finish')
    },
    //路由时抛错的处理
    error: async(ctx,err) =>{

    }
}

注意:只有控制器能正常执行,before和after才能被执行,如果在调用控制器之前抛错或返回了,before和after也不会执行。

默认控制器

当找不到指定的controller时,ec-router会去查找controller目录下的_any.js作为默认控制器。

使用该特性,可以实现自动的RESTful服务:

//_any.js
module.exports = {
    get : async (ctx) => {
        //根椐ctx.ecRouter.resource ,ctx.ecRouter.resourceId及其它query参数自动从数据库获取内容输出
    },
    post: async (ctx) => {
        //实现更新数据
    },
}

错误控制器

在碰到无法正常处理的请求时,ec-router会抛出异常,并在最后catch这些异常,传递给_hook.js控制器的error方法处理(如果没有则只输出到控制台)

config

可以在调用ec-router.dispatcher之前使用loadConfig来修改默认配置(config文件只需定义不使用默认值的项)

{
    type            : 1,                //路由方式
    uriApiName      : 'index',          //使用querystring方式时,指定API文件名,即/apiName?c=xx&m=xx
    uriCParam       : 'c',              //使用querystring方式时,指定控制器的参数名
    uriAParam       : 'a',              //使用querystring方式时,指定控制器方法的参数名
    uriPrefix       : '',               //API路径前缀,如: /prefix/controller/action
    uriDefault      : '/index',         //默认uri path
    apiVer          : false,            //是否支持版本声明
    apiVeRegex      : /^v?(\d){1,2}(\.[\d]{1,2})?$/, //版本规则,
    controllerPath  : 'controllers',    //控制器文件所在目录,相对于app根目录
    allowMethod     : ['get','post','put','delete','options'] //允许的请求方法
}

数据访问

ec-router并不包括数据访问的处理,以下只是一些建议:

  1. 通过koa的middleware,建立一个数据连接的中间件,建立和获取连接,并将连接句柄注入为ctx.dbconn,然后可以在controller中使用
  2. 通过_hook的before建立数据连接获取,注入ctx.dbconn
  3. 建立dao基类,然后在其之上实现各对象的dao,直接使用dao调用

License

MIT is open-sourced software licensed under the MIT license.

Author

Tim[email protected]