Open leandrodamascena opened 1 year ago
@leandrodamascena thanks for raising the issue. Marking it as a bug and will prioritize on fixing it.
@leandrodamascena thanks for raising the issue. Marking it as a bug and will prioritize on fixing it.
Thank you @hawflau! I will let our customer know the SAM project is fixing this bug! 💯
Hi @leandrodamascena
As we discussed offline, we need to de-prioritize it for now. At high level;
rawPath
variable inside the function payload is actually generated from the mapping that sam local start-api
creates, which is missing the stage information from API resource. Changing just event payload will not resolve this problem, in fact it might make it worse given that some customers might already adopted current behavior./stage/path
and /path
) but this will introduce more changes to the existing functionality since SAM CLI don't parse staging information as of now (ex; there might be multiple stages for an API resource, which is not available at the moment).Thanks!
Also just got tripped up by the different case type for headers in SAM local vs AWS (for example, on local, the host header is Host
in AWS, the host header is host
). Now I must account for both scenarios and have local specific code deployed to production to support each form.
I can see this has been marked as a feature, not a bug. If SAM is intended to provide a way to run Lambda functions locally, any differences in the local environment compared to in AWS are clearly a bug. This is basic stuff for running anything locally, having a realistic production like environment is a must have, not a nice to have.
I should point out here that Serverless Framework does not have this issue (or a bunch of other issues I've encountered with SAM, like no easy local debugging of my TypeScript files, not picking up changes for hot reload, needing to do a "cold start" for every change).
I have related bug. I'm using AWS SAM with Powertools for AWS Lambda .
Using SAM, I created an HTTP API and a Lambda function with event on GET /health request:
# ...
AwesomeApi:
Type: AWS::Serverless::HttpApi
Properties:
Name: !Sub "awesome-api-${Env}"
StageName: !If [IsProductionEnv, "api", !Sub "${Env}-api"]
DefaultRouteSettings:
DetailedMetricsEnabled: true
ThrottlingBurstLimit: 100
ThrottlingRateLimit: 100
# ...
HealthLambdaFn:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub "health-lambda-fn-${Env}"
CodeUri: src/lambda/functions/api_users/
Handler: handler.lambda_handler
Role: !GetAtt BasicLambdaRole.Arn
Events:
CheckHealth:
Type: HttpApi
Properties:
ApiId: !Ref AwesomeApi
Path: /health
Method: GET
TimeoutInMillis: 12000
PayloadFormatVersion: "2.0"
According to the Powertools documentation, I use APIGatewayHttpResolver
:
from aws_lambda_powertools import Logger
from aws_lambda_powertools.event_handler import APIGatewayHttpResolver
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.utilities.typing import LambdaContext
logger = Logger()
app = APIGatewayHttpResolver()
@app.get("/health")
def check_health():
return {"status": "healthy"}
@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_HTTP)
def lambda_handler(event: dict, context: LambdaContext) -> dict:
return app.resolve(event, context)
And it works when I deploy it to AWS. But when running locally via sam local start-api
I get 404 because locally the event is different and route unmatched.
To fix this, I have to change the event on the fly:
@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_HTTP)
def lambda_handler(event: dict, context: LambdaContext) -> dict:
# Fix for SAM local
if environ.get("AWS_SAM_LOCAL"):
event["rawPath"] = "/dev-api" + event["rawPath"]
event["requestContext"]["http"]["path"] = "/dev-api" + event["requestContext"]["http"]["path"]
return app.resolve(event, context)
Description:
Hello everybody! Following @moelasmar's recommendation in issue #5579, I am opening a new issue with more information about the case. Along with Ruben, I'm building Powertools for AWS Lambda and a customer has raised this issue: aws-powertools/powertools-lambda-python#2765.
I'll go into more detail throughout this issue, but to summarize: the v2.0 payload of an HTTP API (
AWS::Serverless::HttpApi
) behaves differently when usingsam local start-api
and when running in the API Gateway + Lambda environment on AWS.In order not to focus on a specific tool, I will not consider the use of Powertools here, but only payloads. I think it will be easier to understand if this is expected behavior from the SAM CLI or a possible bug.
Steps to reproduce:
I'm using the following SAM template with a specific StageName for HttpApi:
And I have the following Lambda code:
The requirements.txt is the basic with only
requests
library and I'm runningsam build
andsam local start-api
After that, I invoked the URL
http://127.0.0.1:3000/hello
just to print the payload I get in the Lambda function.Observed result:
When running it locally, I see that rawPath and path are just
/hello
, it's not adding the stage name. When I run this in the API Gateway + Lambda environment I see that the rawPath and path are/prod/hello
, that is, the stage name is added.Below are the payloads received in both environments. An important point to report here is that in API Gateway I deployed this stack using the default APIGateway URL (....execute-api.us-east-1.amazonaws.com) and with a custom domain. In both scenarios the behavior are the same: the stage is added to the rawPath and path.
Payload using SAM CLI
Payload using API Gateway + Lambda
Expected result:
When running in a local environment with
sam local start-api
it is expected to behave the same as when running in an AWS environment. The user can rely on therawPath
andpath
fields to make decisions such as which internal function to call, which route to map (in micro-frameworks, for example), among other things. I don't know if this is the expected behavior of the SAM CLI, but I think the experience should be the same when running it locally.Additional environment details (Ex: Windows, Mac, Amazon Linux etc)
Thank you very much for your attention. I hope that we can clarify this things and perhaps improve the user experience even more.