动态地将处理程序添加到快速路由功能

时间:2017-05-05 18:05:48

标签: node.js express typescript

我的意思是,假设我有这个代码:

var ARouter = Router();    

@Validate({
    params: {
        id: joi.number(),
        x: joi.number()
    }
})
@HttpGet('/foo/:id')
foo(req: Request, res: Response) {
    res.send('in foo').end();
}

function HttpGet(path: string) {
    return function (target: ApiController, propertyName: string, descriptor: TypedPropertyDescriptor<RequestHandler>) {
        ARouter.get(path, descriptor.value);
    }
}

我在这里有一个路由器,装饰器和一个foo函数。 HttpGet装饰器创建一个路径'foo /:id'和foo作为ARouter中唯一的处理程序。

我希望@validate装饰器将另一个处理程序(特定的函数中间件,将在foo之前调用)添加到foo路由处理程序堆栈。 例如喜欢它是router.get('/ foo /:id /,validationFunction,foo)。

有没有办法动态地将处理程序添加到路由器中的foo路由?

谢谢!

1 个答案:

答案 0 :(得分:0)

基于decorators documentation

  

当多个装饰器应用于单个声明时,它们的   评价类似于数学中的函数组成。在这   模型,当组成函数f和g时,得到的复合(f∘   g)(x)等于f(g(x))。

所以你可以这样做:

function validate(params: any, fn: (req: Request, res: Response) => void) {
    // validate data here and based on that decide what to do next
}

function Validate(params: any) {
    return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        const newDescriptor = Object.assign({}, descriptor);

        newDescriptor.value = function(req: Request, res: Response) {
            validate(params, descriptor.value);
        }

        return newDescriptor;
    }
}

并更改装饰者的顺序:

@HttpGet('/foo/:id')
@Validate({
    params: {
        id: joi.number(),
        x: joi.number()
    }
})
foo(req: Request, res: Response) {
    res.send('in foo').end();
}

(请记住,我还没有测试过它)