Set operationName in local API request context#2458
Conversation
|
Oh shoot, this doesn't quite fix the issue because of the route deduping done here: The deduping combines all of the routes that share the same path (but different methods) into a single aws-sam-cli/samcli/lib/providers/api_collector.py Lines 152 to 166 in 3ee79db However, they should be treated as separate routes if they have different operation names. Given this, should we still be deduping the routes at all? I can't quite tell from the comments what the original rationale was. It looks like this was introduced in #1239. @viksrivat: do you happen to remember? |
|
@ramosbugs SAM CLI uses Flask under the hood to create an API Gateway like endpoint. We need to dedup the urls and methods to wire it up with Flask. |
@jfuss: thanks for the quick reply! the call site you linked to is passing the applicable HTTP method(s) to Flask as an argument: The Locally, I replaced this line with Consequently, it seems safe to remove the dedupe functionality, which may have been based on a misunderstanding of Flask's behavior, or some limitation that used to exist but no longer does. |
|
or maybe the issue is this: the line above says that it should dedupe based on |
|
@jfuss: any thoughts on my comments above? iiuc, the current SAM CLI isn't capable of testing most REST APIs, which frequently use multiple HTTP methods (GET/POST/DELETE, etc.) for a single route to represent different operations (i.e., create the resource, fetch the resource, delete the resource). Flask definitely supports this, but not the way that the SAM CLI is currently leveraging Flask... I'm happy to help contribute a fix if we can align on the approach :-) |
|
See https://github.com/ramosbugs/aws-sam-rest-api-repro for an example repro of the route dedupe bug described above (on the latest version of this PR) |
|
@ramosbugs Thanks for providing the repro app. It is super helpful. I need to do some deeper testing on what is going on here, as API Gateway doesn't document this (from what I can tell). What I am going to try and answer:
From your example, it is clear how this will work in the non swagger model but we need to make sure we support both. I would like to get integrations tests added for various combinations, without that we will risk missing or breaking this. I am happy to add them myself but need to dig deeper and understand this all, especially because it is not documented behavior of API Gateway. |
|
thank you @jfuss! great points. once implemented, I think this should simplify the internal routing logic that Lambda functions need to implement: based on unique operation ID rather than (HTTP method, route) pair, which partially duplicates the routing logic API Gateway does for us. |
|
@ramosbugs I am not sure I get your point on: "I think this should simplify the internal routing logic that Lambda functions need to implement: based on unique operation ID rather than (HTTP method, route) pair, which partially duplicates the routing logic API Gateway does for us." My understanding of API Gateway is that the routing done is by HTTP method and route. Operation ID is optional, so I don't quite understand how this improves any routing logic in SAM CLI. |
|
The OperationName is only sent to the Lambda Function from API Gateway V1 (Rest API). Rest API's only support payload version 1.0. However for Http Apis (v2), API Gateway never sends the OperationName (payload version 1 or 2). With this change, we need to reflect the same behavior as API Gateway. @ramosbugs Are you willing to make changes to this PR or should I take it over completely? |
it's a somewhat minor point, but if you have a single Lambda function that's serving multiple API endpoints (particularly useful for compiled languages to avoid emitting dozens of binaries), that Lambda function has to know which endpoint handler to invoke internally. if the operation name/ID from the OpenAPI spec is present in the request, that provides a convenient input for making that routing decision. it also means that only the API Gateway even needs to be aware of the URL paths (e.g.,
it's been awhile since I've touched this code and you're much more familiar with this codebase than I am, so please feel free to take it over :-) |
…cli into develop-operation-name
|
@ramosbugs I have raised a PR against your PR branch to add the integration tests, and only let operationname send to APIGW v1. Can you please merge it and get it into this PR? ramosbugs#1 Thanks! |
Add integration test to PR aws#2458, and resolve the dedupe_function_routes issue
merged, thank you! |
| domain_name=None, | ||
| request_time_epoch=int(time()), | ||
| request_time=datetime.utcnow().strftime("%d/%b/%Y:%H:%M:%S +0000"), | ||
| operation_name=None, |
There was a problem hiding this comment.
Is this used for all API Events? If so, shouldn't we model different RequestsContext's for different events?
There was a problem hiding this comment.
Looks like we have different RequestContext for V1 and V2 events. This is for v1 events only, it only used in
For v2 api, it is using RequestContextV2:
The httpapi with payload v1 is also using this type of event. For httpapi or restapi without "operationName", it won't be passed into the RequestContext map: https://github.com/aws/aws-sam-cli/pull/2458/files#diff-0ffb9968392fca338c633173f593848b7301fb166fcf56bd3178994d15e1c88aR150
|
thank you all! |
Which issue(s) does this change fix?
Fixes #2457.
Why is this change necessary?
The
operationNamefield is currently missing from the API Gateway proxy request context, which prevents certain Lambda functions from working correctly in the local environment.How does it address the issue?
This PR adds the missing
operationNamebased on the SwaggeroperationId, as the production AWS Gateway does.What side effects does this change have?
Hopefully none :-)
Checklist
make prpassesmake update-reproducible-reqsif dependencies were changedBy submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.