koa 根据目录结构自动注册嵌套路由

343 阅读1分钟

要实现的目的 只需定义出路由文件目录结构,路由注册由目录结构自动完成。

这么做的好处 是从文件目录能一目了然的知道项目路由的结构,清晰划分文件目录的同时定义了路由的嵌套结构,省事又清晰,寻找路由文件的时候不容易迷乱。

这么做的执着 是怎样才能在这种方式下定义出这样的路由:

  • /admin/user/:id/order
  • /admin/xxx/yyy/zzz/:id
  • /admin/aaa/bbb/ccc/ddd
  • /admin/user 又如何才能以同样直观的方式,在任一路由层级添加拦截与请求预处理呢,比如在 /admin 层级添加权限拦截。

成败的关键 在于这份执着能不能以恰到好处的程度完成功能,不能牵强,过于执着亦是失败。

我定义了如下目录实现了上面的路由定义

仓库地址 gitee.com/codePrince/…

├── admin
│   ├── aaa
│   │   ├── a-one.js
│   │   ├── a-two.js
│   │   └── bbb
│   │       └── ccc
│   │           └── ddd.js
│   ├── dept
│   │   └── index.js
│   ├── index.js
│   ├── user.js
│   ├── user_id
│   │   ├── index.js
│   │   └── order.js
│   └── xxx
│       ├── index.js
│       └── yyy
│           └── zzz.js
  • 其中 user_id 会被解释为 user/:id 其中的控制器文件定义:
// /aaa/bbb/ccc/ddd.js
const BaseController = require("../../../../base")

module.exports = class extends BaseController{
	constructor(){
		super()
		this.get.params = ['id']
	}
	async get(ctx, next){
		cx.body = {params: ctx.params}
	}
        async put(ctx, next){
		ctx.success("dept put yes")
	}
        async post(ctx, next){
		ctx.success("dept post yes")
	}
}
  • 如果你的环境支持注解,那可以把 params 的设置用注解来做,更加直观一点 任一层级拦截或前置处理
// admin/index.js
// admin 下任一级别的路由都会经过这里
const BaseController = require("../base")

module.exports = class extends BaseController{
	constructor(){
		super()
	}
	async _before(ctx, next){
		console.log("admin level #");
		await next()
		// ctx.throw(401)
	}
	async get(ctx){
		this.success()
	}
}
  • 主要定义 restful 风格的接口,也可以实现非 restful 风格的接口,比如定义方法名 getList 对应的路由就是 get /list
  • 具体实现在仓库 controller/init.js 中