export default class Sign { @post('/login') async login (ctx: Context) { const { email, password } = ctx.request.body; const users = await userDao.getUser({ email }); // ... return ctx.body = { code: 0, message: '登录成功', data }; } @post('/register') async register (ctx: Context) { const { email, password } = ctx.request.body; const salt = makeSalt(); // ... return ctx.body = { code: 0, message: '注册成功!', data } } }
收集元数据和添加路由
我们已经把装饰器添加到对应控制器的方法上了,那么怎么把元数据收集起来呢?这就需要用到 node 提供的 fs 文件模块,node服务第一次启动的时候,扫描一遍controller文件夹,收集到所有控制器模块,结合装饰器收集到的metadata,就可以把对应的方法添加到 koa-router。
import 'reflect-metadata' import fs from 'fs' import path from 'path' import { ROUTER_MAP } from './constant' import { RouteMeta } from './type' import Router from 'koa-router' const addRouter = (router: Router) => { const ctrPath = path.join(__dirname, 'controller'); const modules: ObjectConstructor[] = []; // 扫描controller文件夹,收集所有controller fs.readdirSync(ctrPath).forEach(name => { if (/^[^.]+?\.(t|j)s$/.test(name)) { modules.push(require(path.join(ctrPath, name)).default) } }); // 结合meta数据添加路由 modules.forEach(m => { const routerMap: RouteMeta[] = Reflect.getMetadata(ROUTER_MAP, m, 'method') || []; if (routerMap.length) { const ctr = new m(); routerMap.forEach(route => { const { name, method, path } = route; router[method](path, ctr[name]); }) } }) } export default addRouter
最后
这样对koa项目脚手架的改造基本完成,源码请查看koa-server