I developing a decorator to add middlewares to a AWS lambda, here is the source code. My inspiration in this, is the source code of mediator (Specifically, the class "RequestHandlerWrapperImpl" in this link). So I took the C# code and tried to pass it to Typescript. The simplified code is this.
// Used Types
type HandlerDelegate = () => Promise<APIGatewayProxyResult>;
type Handler = (event: APIGatewayProxyEvent) => Promise<APIGatewayProxyResult>
type Middleware = (event: APIGatewayProxyEvent, next: HandlerDelegate) => Promise<APIGatewayProxyResult>;
// Middlewares
const first = (event: APIGatewayProxyEvent, next: HandlerDelegate) =>{
console.log("first in")
const response = next();
console.log("first out")
return response;
};
const second = (event: APIGatewayProxyEvent, next: HandlerDelegate) =>{
console.log("second in")
const response = next();
console.log("second out")
return response;
};
// Executable logic
const read = forHandler(async () : Promise<APIGatewayProxyResult>
=> APIResponse.createSuccess(HttpStatusCode.OK, "handler"))
.addMiddleware(first)
.addMiddleware(second)
.finish;
// finish method
const finish = (event: APIGatewayProxyEvent) : Promise<APIGatewayProxyResult> => {
let result: HandlerDelegate = () => handler(event);
for (let i = 0; i < middlewares.length; i ) {
result = () => middlewares[i](event, result);
}
return result();
}
The expected log is this:
"first in"
"second in"
"handler"
"second in"
"first in"
But, is this, 'till a overflow exception
"second in"
"second in"
"second in"
"second in"
"second in"
"second in"
"second in"
"second in"
Can someone explain why ocurr this? I think is because at the line
result = () => middlewares[i](event, result);
I replace entirely the result variable (in both "sides"). So, instead of being recursive, it just loops. Also, how I can make it work as expected?
CodePudding user response:
The solution was modified the finish function, to this:
const finish = (event: APIGatewayProxyEvent) : Promise<APIGatewayProxyResult> => {
let result: HandlerDelegate = () => {
return handler(event);
};
for (let i = 0; i < middlewares.length; i ) {
let resultCallback = result;
result = () => {
return middlewares[i](event, resultCallback);
};
}
return result();
}
With this, the result function is not overwrited, and we make the pipeline work