我正在尝试将方法和函数注册到express中。例如:
@Controller("/api/users/")
export class UserController {
constructor() {
console.log("constructor")
}
@GET("get/:id")
public getUser(req: Request, res: Response) {
}
}
装饰器如下:
export function Controller(basePath: string) {
return function(target: any) {
const instance = new target();
const methodList = Object.getOwnPropertyNames(target.prototype).map(m => target.prototype[m])
methodList.forEach(method => {
console.log(method) //<--- What should I put here?
})
}
}
export function GET(url: string) {
return function (target: any, propertyKey: String, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
descriptor.value.url = url
}
return descriptor;
}
}
如何在不调用 getUser 函数的情况下获取值“get/:id”?
目标是将
getUser
引用到 Express 路由器。所以在这种情况下,我想将 getUser(req, res)
注册为 express.router.get(basePath + url, method)
我不知道该放什么来替换
console.log(method)
来注册方法
这个想法是让你的
GET
装饰器使用 reflect-metadata 存储 url
当
@Controller
被评估时,@Get()
将会被执行并存储元数据。然后您所要做的就是检索所有存储的元数据。
export function Controller(basePath: string) {
return function(target: any) {
const instance = new target();
const methodList = Object.getOwnPropertyNames(target.prototype).map(m => target.prototype[m])
methodList.forEach(method => {
const url = Reflect.getOwnMetadata("my-get-url", target.prototype, m)
})
}
}
export function GET(url: string) {
return function (target: any, propertyKey: String, descriptor: PropertyDescriptor) {
Reflect.defineMetadata("my-get-url", url, target, descriptor.propertyKey
// ...
}
}
请注意,如果您想让它与继承一起使用,这个简单的实现需要额外的工作。
这是我创建@aspectjs/core的原因之一。
使用aspectjs,你可以像这样简单地解决这个问题:
import {
AnnotationFactory,
AnnotationKind,
} from '@aspectjs/common';
import { Aspect, Compile, on, AdviceContext, getWeaver } from '@aspectjs/core';
// Define your annotations
const af = new AnnotationFactory('my-org');
const GET = af.create(AnnotationKind.METHOD, 'GET', (url: string) => {});
const Controller = af.create(AnnotationKind.CLASS, 'Controller', (url: string) => {});
// Create an aspect that registers your controller
@Aspect()
class RegisterExpressControllerAspect {
@Compile(on.classes.withAnnotations(Controller))
registerController(ctxt: AdviceContext) {
const get = ctxt.annotations(GET).find({searchParents: true})[0]!;
const [url] = get.args
console.log(url)
}
}
getWeaver().enable(new RegisterExpressControllerAspect())
@Controller("/api/users/")
export class UserController {
constructor() {
console.log("constructor")
}
@GET("get/:id")
public getUser(req: Request, res: Response) {
}
}