在考究了nodejs以及nestjs后,觉得nestjs用的不是特别爽,于是开始不自量力的写起了这个框架玩,希望能在造轮子的过程中学到更多有趣的东西。
nestjs基于express,我的quick-d基于koa,目前只是雏形阶段,还在慢慢搭建与完善。
牢记非侵入式设计!!!
牢记非侵入式设计!!!
牢记非侵入式设计!!!
目录
一、控制层装饰器(@Controller)
二、路由装饰器(@Request,@Get、Post、Put、DeleteRequest)
三、参数装饰器(@BodyParam,@Query)
四、全局错误处理 异常解决方案
五、自动装载与容器管理
核心技术
装饰器、反射
一、控制层装饰器
common/Controller.js 文件中
const Controller = (path: string = ''): ClassDecorator => {
return (originClass: Function) => {
if (global['$Quick-D'] === undefined) {
// 这里相当于定义一个容器运行环境在全局
global['$Quick-D'] = {}
global['$Quick-D']['controllers'] = {}
}
// 将这个添加了该装饰器的对象加到容器中管理
global['$Quick-D']['controllers'][originClass.name] = originClass
// 将装饰器函数获取的参数通过反射机制加到原型链上
Reflect.defineMetadata('path', path, originClass)
Reflect.defineMetadata('router', new Router(), originClass)
}
}
二、路由装饰器
三、参数装饰器
四、全局错误处理 异常解决方案
五、自动装载与容器管理
index.js 文件中
/**
* 接收主程序传来的 APP 实体
*/
let APP = undefined
/**
* 反射获取controller中的数据
* @param controller 路由控制层对象
* @returns {{path: any, routes: any, router: any}}
*/
const reflectGetData = controller => {
return {
path : Reflect.getMetadata('path', controller),
router : Reflect.getMetadata('router', controller),
routes : Reflect.getMetadata('routes', controller)
}
}
/**
* 为框架注册 koa应用实体
* @param app koa应用实体
*/
const registerApp = (app: Koa) => {
APP = app
APP.use(koaBodyparser())
const oldListen = APP.listen
APP.listen = (...args) => {
const controllers = global['$Quick-D']['controllers']
for (const controllerName in controllers) {
const controller = controllers[controllerName]
const instance = new controller()
const {
path, router, routes
} = reflectGetData(controller)
}
}
oldListen.call(APP, ...args)
}
src/app.js 项目入口文件中
import Koa from 'koa'
import config from './config'
import { registerApp } from '~/lib/decorator/quick-d'
global.MAIN_APP = new Koa()
registerApp(MAIN_APP)
const controllersFileNames = require('fs').readdirSync(__dirname + '/controller')
for (let controllersNameIndex in controllersFileNames) {
const controllersName = controllersFileNames[controllersNameIndex]
if (/\.js$/.test(controllersName)) {
require(`@/controller/${controllersName}`)
}
}