-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
APIGW NG: introduce new unified path style #11350
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
self.router.add( | ||
path="/restapis/<api_id>/<stage>/_user_request_/<greedy_path:path>", | ||
endpoint=deprecated_route_endpoint, | ||
strict_slashes=True, | ||
), | ||
# add the localstack-specific so-called "path-style" routes when DNS resolving is not possible | ||
self.router.add( | ||
path=f"{self.EXECUTE_API_INTERNAL_PATH}/<api_id>/", | ||
endpoint=self.handler, | ||
defaults={"path": "", "stage": None}, | ||
strict_slashes=True, | ||
), | ||
self.router.add( | ||
path=f"{self.EXECUTE_API_INTERNAL_PATH}/<api_id>/<stage>/", | ||
endpoint=self.handler, | ||
defaults={"path": ""}, | ||
strict_slashes=False, | ||
), | ||
self.router.add( | ||
path=f"{self.EXECUTE_API_INTERNAL_PATH}/<api_id>/<stage>/<greedy_path:path>", | ||
endpoint=self.handler, | ||
strict_slashes=True, | ||
), |
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.
A better strategy might be to match only <api_id>
and <api_id>/<greedy_path:path>
and have to do a bit more work when routing the request. It is added work on the rest api but would help us support HTTP api with less mess
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.
We had a lengthy discussion about this, and the TLDR; is this:
We're using the router to do as much parsing as it can, and if we were to remove the stage from the path, we would still need to manually parse it from every request by checking the first "resource" of the path and assigning it to the stage name.
For HTTP API, you can define a $default
stage, so if you do not specify a stage name, it will fallback to the default. That leads to the registered routes being somewhat misleading, because if you target an HTTP API with a $default stage configured with the following path: test/test-path
, then in our edge router endpoint, test
will be assigned to the stage value.
The next check is to verify if that test
is in the existing stages
, and if not, assign the stage value to $default
.
We don't use the <greedy_path:path>
value in the rest of the invocation, as it is URL-decoded, and we need the raw value. In the rest of the logic, we first use RAW_URI
which contains the entire path of the request, and we do manipulation to remove the stage name if the request is prefixed with it. The stage
parameter here is only to help us get that first "resource" of the path, it being rightly the stage name or not is not really important, we do not know yet if the request is proper or not.
We've also decided to model the edge router rules to the REST API format, as stage
is mandatory. It will be a bit of a workaround to support all kind of API with the same routes, but if properly documented, should be alright.
This Edge router endpoint can be seen as a "first pass" routing, trying to catch all API Gateway request and doing as much work as possible, and then it's up to us to properly route the request to the right API Gateway Resource/Route of the API.
I agree with the sentiment that those routes will match something a bit "misleading" in assigning a stage value to something that isn't a stage value, but we would need to manually parse the first part to check if it is a stage value or not, so letting the router do the work for us is okay, as long as the process is properly documented.
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.
Thanks @bentsku for tackling this and be always ready for good discussion and clarification!
I really appreciate the switch to internal request using _aws
🚀
08c1821
to
e03967a
Compare
Motivation
In LocalStack API Gateway, we currently have a specific path-style format to call
execute-api
:http(s)://<your-domain>:<port>/restapis/<api_id>/<stage>/_user_request_/<your-path>
.The actual AWS format is this, with the host:
http(s)://<api-id>.execute-api.<domain>/<stage>/<your-path>
There are multiple problems with our current "path style" format:
restapis
in the name but is shared with HTTP and WebSockets API in APIGW v2This PR introduces a new path format for API Gateway, available with the "Next Gen" provider:
http(s)://<your-domain>:<port>/_aws/execute-api/<api-id>/<stage>/<your-path>
This new format follows the same order as AWS, is clearer about the LocalStack-only part, is on the
_aws
namespace, and hasexecute-api
in the name, which maps to the URL people are used to see.It also sets up a deprecation path for the previous "path style" and log a message when people uses it with the new provider. We will also need to update the documentation accordingly.
Deprecation message:
Changes
_user_request_
endpoint when using the NG provder