目的
用 ts + reflect-metadata 实现 spring boot rest注解。
在 java 和 spring boot 项目,随处可见注解,给大家看一段代码
@RequestMapping("/accounts")
class AccountController {
@GetMapping("/info")
getId(ctx) {
ctx.body = {
"id": 10086,
};
}
}
熟悉 java 的人 会看着好眼熟, 但其实这是 js 的代码。 结合 ts,reflect-metadata, 我们可以写出类似 java 注解 的代码及实现功能。
工具类方法
const METHOD_METADATA = 'method';
const PATH_METADATA = 'path';
const createMappingDecorator = (method: string) => (path: string): MethodDecorator => {
return (target, key, descriptor) => {
Reflect.defineMetadata(PATH_METADATA, path, descriptor.value);
Reflect.defineMetadata(METHOD_METADATA, method, descriptor.value);
}
}
const GetMapping = createMappingDecorator('GET');
function RequestMapping(path: string): ClassDecorator {
return target => {
Reflect.defineMetadata(PATH_METADATA, path, target);
}
}
function mapRoute(instance: Object) {
const prototype = Object.getPrototypeOf(instance);
// 筛选出类的 methodName
const methodsNames = Object.getOwnPropertyNames(prototype)
.filter(item => <any>_.isFunction(prototype[item]) && item != "constructor");
return methodsNames.map(methodName => {
const fn = prototype[methodName];
// 取出定义的 metadata
const path = Reflect.getMetadata(PATH_METADATA, fn);
const method = Reflect.getMetadata(METHOD_METADATA, fn);
return {
path,
method,
fn,
methodName
}
})
}
结合 koa, koa-router 实现的 rest 请求
const Koa = require('koa');
const Router = require('@koa/router');
const app = new Koa();
let router = new Router();
let requestPrefix = Reflect.getMetadata(PATH_METADATA, AccountController);
let routeInfo = mapRoute(new AccountController());
routeInfo.forEach((item) => {
router[item.method.toLowerCase()](item.path, item.fn);
}
);
router.prefix(requestPrefix);
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000, () => {
console.log("listen 3000")
});
参考文档:
https://github.com/koajs/router/blob/HEAD/API.md#module_koa-router
https://github.com/rbuckton/reflect-metadata
https://jkchao.github.io/typescript-book-chinese/tips/metadata.html#controller-%E4%B8%8E-get-%E7%9A%84%E5%AE%9E%E7%8E%B0
网友评论