Skip to content

Bug: APIGatewayRestResolver fails to route when "/" appears at end of route name #1552

Closed
@walmsles

Description

@walmsles

Expected Behaviour

Given I am using APIGatewayRestResolver and I define a route as follows:

from aws_lambda_powertools.event_handler import APIGatewayRestResolver

app = APIGatewayRestResolver()

@app.get("/hello")
def hello_world():
    return {"message": "Hello World"}

I expect the following 2 GET request URLs:

  1. https://myapigwid.execute-api.ap-southeast-2.amazonaws.com/Prod/hello/
  2. https://myapigwid.execute-api.ap-southeast-2.amazonaws.com/Prod/hello

to return the same response:

{"message":"Hello World"}

Current Behaviour

Given I am using APIGatewayRestResolver and I define a route as follows:

@app.get("/hello")
def hello_world():
    return {"message": "Hello World"}

When I use the following URL:

  1. https://myapigwid.execute-api.ap-southeast-2.amazonaws.com/Prod/hello/

AWS Lambda Powertools returns a 404 not found response:

{"statusCode":404,"message":"Not found"}

Code snippet

from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools import Logger

app = APIGatewayRestResolver()
logger = Logger()

@app.get("/hello")
def hello_world():
    return {"message": "Hello World"}

@logger.inject_lambda_context(log_event=True)
def lambda_handler(event, context):
    logger.info("Executing app.resolve")
    return app.resolve(event, context)

Possible Solution

Route resolution uses the path attribute of the AWS API Gateway Lambda event so that the 2 URLs (one with trailing "/") are no longer the same even though the API Gateway Service treats the routes correctly and executes the expected Lambda function.

I would suggest that during route resolution trailing "/" characters be removed and not considered in route resolution.

Unsure if this would be considered a breaking change and whether any customers are using this behaviour - I would not think this behaviour would be in use y customers but am unsure 😬

Steps to Reproduce

Create and deploy the SAM CLI Hello World function then replace the app.py with my code snippet above which has replaced it with AWS Lambda powertools resolver once deployed try loading the API in browser with and without trailing "/" character

AWS Lambda Powertools for Python version

latest

AWS Lambda function runtime

3.9

Packaging format used

PyPi

Debugging logs

START RequestId: a6a6f7b6-84db-4e1b-bfa6-59af38e9927d Version: $LATEST  2022/09/29/[$LATEST]c9ddb616b59546349b99ceaf1ef78e36

2022-09-29T17:49:38.102+10:00   {"level":"INFO","location":"decorate:352","message":{"resource":"/hello","path":"/hello","httpMethod":"GET",....} 2022/09/29/[$LATEST]c9ddb616b59546349b99ceaf1ef78e36

2022-09-29T17:49:38.102+10:00   {"level":"INFO","location":"lambda_handler:26","message":"Executing app.resolve","timestamp":"2022-09-29 07:49:38,102+0000","service":"service_undefined","cold_start":false,"function_name":"sam-app-HelloWorldFunction-nF3rtaBXzZ7S","function_memory_size":"128","function_arn":"arn:aws:lambda:ap-southeast-2:308836149415:function:sam-app-HelloWorldFunction-nF3rtaBXzZ7S","function_request_id":"a6a6f7b6-84db-4e1b-bfa6-59af38e9927d","xray_trace_id":"1-63354e12-521e23257116158e4057dc1e"}    2022/09/29/[$LATEST]c9ddb616b59546349b99ceaf1ef78e36

2022-09-29T17:49:38.103+10:00   END RequestId: a6a6f7b6-84db-4e1b-bfa6-59af38e9927d 2022/09/29/[$LATEST]c9ddb616b59546349b99ceaf1ef78e36

2022-09-29T17:49:38.103+10:00   REPORT RequestId: a6a6f7b6-84db-4e1b-bfa6-59af38e9927d Duration: 1.88 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 57 MB   2022/09/29/[$LATEST]c9ddb616b59546349b99ceaf1ef78e36

2022-09-29T17:49:41.754+10:00   START RequestId: e119c41b-45a7-464b-8931-cde0f6b2b51e Version: $LATEST  2022/09/29/[$LATEST]c9ddb616b59546349b99ceaf1ef78e36

2022-09-29T17:49:41.755+10:00   {"level":"INFO","location":"decorate:352","message":{"resource":"/hello","path":"/hello/","httpMethod":"GET",....} 2022/09/29/[$LATEST]c9ddb616b59546349b99ceaf1ef78e36

2022-09-29T17:49:41.755+10:00   {"level":"INFO","location":"lambda_handler:26","message":"Executing app.resolve","timestamp":"2022-09-29 07:49:41,755+0000","service":"service_undefined","cold_start":false,"function_name":"sam-app-HelloWorldFunction-nF3rtaBXzZ7S","function_memory_size":"128","function_arn":"arn:aws:lambda:ap-southeast-2:308836149415:function:sam-app-HelloWorldFunction-nF3rtaBXzZ7S","function_request_id":"e119c41b-45a7-464b-8931-cde0f6b2b51e","xray_trace_id":"1-63354e15-4cad301429daa2311eaa530a"}    2022/09/29/[$LATEST]c9ddb616b59546349b99ceaf1ef78e36

2022-09-29T17:49:41.756+10:00   END RequestId: e119c41b-45a7-464b-8931-cde0f6b2b51e 2022/09/29/[$LATEST]c9ddb616b59546349b99ceaf1ef78e36

2022-09-29T17:49:41.756+10:00   REPORT RequestId: e119c41b-45a7-464b-8931-cde0f6b2b51e Duration: 1.68 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions