-
Notifications
You must be signed in to change notification settings - Fork 171
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
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, https
making 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
BaseRouter
class. Theresolve
method 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 existinghandleError
method.Changes
BaseRouter
to have. oncrete implementation ofresolve
methodAPIGatewayProxyResult
type that lambda expectsresolve
function is implemented in the base classthis
context 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.