先看最终的代码
启动服务
模块化
控制层
截图摘自于 github.com/chelizichen… 中的 test 目录下
联系方式:1347290221@qq.com
微信:13476973442 备注(掘金)
作者并没有看过 Nest 的源码,一开始也没有想做一个 Nest-Like 的意思,只是觉得好玩就模仿了几个常用的Api。而后在暑期实习的时候在公司拓展了一下整个代码,在8月底决定做一个富含装饰器并且使用了DI 设计思想的库,询问英语专业的同学如何起名,最后起名为 Ado-Node。
第一章 参数装饰器
@Body @Query 和实现方式
Nest 底层是由 Express 构建的,我们可以将 @Body 和 @Query 看作为
@Body = request.body
@Query = request.query
@Params = request.params
我们需要使用到 Reflect-Metadata 这个库 和 TypeScript 自带的装饰器函数
实现代码
我定义了一个元数据
function Query(): ParameterDecorator {
return function (
target: Object,
propertyKey: string | symbol,
parameterIndex: number
) {
ref.def(
propertyKey as string,
parameterIndex,
target.constructor.prototype,
":query"
);
};
}
并且修改了函数的参数
function useArgs(
propertyKey: string,
target: Object,
req: Request,
res: Response
): any[] {
const hasQuery = ref.get(
propertyKey as string,
target.constructor.prototype,
":query"
);
const hasBody = ref.get(...);
const hasHeaders = ref.get(...);
const hasRequest = ref.get(...);
const hasResponse = ref.get(...);
let arg = [];
if (
typeof hasQuery === "number" ||
typeof hasBody === "number" ||
typeof hasHeaders === "number" ||
typeof hasRequest == "number" ||
typeof hasResponse == "number"
) {
arg[hasQuery] = req.query;
arg[hasBody] = req.body;
arg[hasHeaders] = req.headers;
arg[hasRequest] = req;
arg[hasResponse] = res;
return arg;
}
return [req, res];
}
// 而后在 MethodDecorator 里面使用了如下的代码
// 修改了运行时的参数
// 根据条件语句 args 只可能为 原生的 req,res 或者带有装饰器的 @Query @Body
Method (url) : MethodDecorator =>
const fn = descriptor.value;
ref.def(propertyKey as string, URL, target.constructor.prototype, ":url");
descriptor.value = async function (req: Request, res: Response) {
const args = useArgs(propertyKey as string, target, req, res);
target.constructor.prototype[propertyKey](...args);
}