-
Notifications
You must be signed in to change notification settings - Fork 180
feat(event-handler): add resolution logic to base router #4349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
f5d5280 to
14a6f53
Compare
14a6f53 to
7a9b621
Compare
dreamorosi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we added this in a previous PR, but after testing the BaseRouter in a Lambda function behind API Gateway REST I think I found a bug in the proxyEventToWebRequest function.
Specifically, the headers parsing (below), is problematic as it concatenates values if the same header is present in both headers and multiValueHeaders - which seems to be always the case in my tests:
for (const [name, value] of Object.entries(event.headers ?? {})) {
if (value != null) headers.append(name, value);
}
for (const [name, values] of Object.entries(event.multiValueHeaders ?? {})) {
for (const value of values ?? []) {
headers.append(name, value);
}
}For example this request payload (shortened for brevity):
{
"resource": "/",
"path": "/",
"httpMethod": "GET",
"headers": {
"Host": "abcd1234.execute-api.eu-west-1.amazonaws.com",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders": {
"Host": ["abcd1234.execute-api.eu-west-1.amazonaws.com"],
"X-Forwarded-Proto": ["https"]
},
"queryStringParameters": null,
"multiValueQueryStringParameters": null,
"pathParameters": null,
"stageVariables": null,
"requestContext": { ... },
"domainName": "abcd1234.execute-api.eu-west-1.amazonaws.com",
"deploymentId": "abcd123",
"apiId": "abcd1234"
},
"body": null,
"isBase64Encoded": false
}results in this:
console.log(headers.get('Host'));
// abcd1234.execute-api.eu-west-1.amazonaws.com, abcd1234.execute-api.eu-west-1.amazonaws.com
console.log(headers.get('X-Forwarded-Proto'));
// https, httpsmaking the URL parsing at L40 fail together with the request.
Additionally, like in this case, the proxyEventToWebRequest function is called and run twice both when first parsing the request and then again in the except block when trying to run the handleError - is there any way that we can run it only once?
Another thing I noticed is that when using API Gateway REST, the requestContext.path field includes the stage as path prefix, for example in a stage prod making a request to stuff would result in "path":"/prod/stuff".
Do we expect customers to have to set it in as prefix at the router level, or in their route handlers? Should we instead just use the top level path and resource fields which in this case would be respectively /stuff and /?
9bdb0f4 to
17ae585
Compare
I've added logic to check whether the header already includes a value before we append it.
I've moved the creation of the
Agreed, I've changed it to use the top level fields instead. |
|



Summary
This PR implements the final resolution logic for the
BaseRouterclass. Theresolvemethod is no longer abstract and has a concrete implementation where it looks up the route registry using the path and tries to retirve a resolver for the route. If not route is found, we throw aNotFoundErroe. If any exceptions are thrown from the handler, these are caught and handled by the already existinghandleErrormethod.Changes
BaseRouterto have. oncrete implementation ofresolvemethodAPIGatewayProxyResulttype that lambda expectsresolvefunction is implemented in the base classthiscontext is preserved when using decorators.Issue number: closes #4142
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.