Skip to content

Commit 45e6555

Browse files
fix(event_handler): Router prefix mismatch regression after Middleware feat (#3302)
1 parent e9c280b commit 45e6555

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

aws_lambda_powertools/event_handler/api_gateway.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2008,6 +2008,7 @@ def include_router(self, router: "Router", prefix: Optional[str] = None) -> None
20082008
# use pointer to allow context clearance after event is processed e.g., resolve(evt, ctx)
20092009
router.context = self.context
20102010

2011+
# Iterate through the routes defined in the router to configure and apply middlewares for each route
20112012
for route, func in router._routes.items():
20122013
new_route = route
20132014

@@ -2017,7 +2018,8 @@ def include_router(self, router: "Router", prefix: Optional[str] = None) -> None
20172018
new_route = (rule, *route[1:])
20182019

20192020
# Middlewares are stored by route separately - must grab them to include
2020-
middlewares = router._routes_with_middleware.get(new_route)
2021+
# Middleware store the route without prefix, so we must not include prefix when grabbing
2022+
middlewares = router._routes_with_middleware.get(route)
20212023

20222024
# Need to use "type: ignore" here since mypy does not like a named parameter after
20232025
# tuple expansion since may cause duplicate named parameters in the function signature.

tests/functional/event_handler/test_api_gateway.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,25 @@ def base():
11971197
assert result["multiValueHeaders"]["Content-Type"] == [content_types.APPLICATION_JSON]
11981198

11991199

1200+
def test_api_gateway_app_with_strip_prefix_and_route_prefix():
1201+
# GIVEN all routes are stripped from its version e.g., /v1
1202+
app = ApiGatewayResolver(strip_prefixes=["/v1"])
1203+
router = Router()
1204+
1205+
event = {"httpMethod": "GET", "path": "/v1/users/leandro", "resource": "/users"}
1206+
1207+
@router.get("<user_id>")
1208+
def base(user_id: str):
1209+
return {"user": user_id}
1210+
1211+
# WHEN a router is included prefixing all routes with "/users/"
1212+
app.include_router(router, prefix="/users/")
1213+
result = app(event, {})
1214+
1215+
# THEN route correctly to the registered route after stripping each prefix (global + router)
1216+
assert result["statusCode"] == 200
1217+
1218+
12001219
def test_api_gateway_app_router():
12011220
# GIVEN a Router with registered routes
12021221
app = ApiGatewayResolver()

tests/functional/event_handler/test_api_middlewares.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,34 @@ def dummy_route():
397397
assert result["statusCode"] == 200
398398

399399

400+
def test_api_gateway_middleware_with_include_router_prefix():
401+
# GIVEN an App and Router instance
402+
app = ApiGatewayResolver()
403+
router = Router()
404+
405+
def app_middleware(app: EventHandlerInstance, next_middleware: NextMiddleware):
406+
# AND a variable injected into resolver context
407+
app.append_context(injected="injected_value")
408+
return next_middleware(app)
409+
410+
# WHEN we register a route with a middleware
411+
@router.get("/path", middlewares=[app_middleware])
412+
def dummy_route():
413+
# THEN we should have access to the middleware's injected variable
414+
assert app.context["injected"] == "injected_value"
415+
416+
return Response(status_code=200, body="works!")
417+
418+
# WHEN register the route with a prefix
419+
app.include_router(router, prefix="/my")
420+
421+
# THEN resolving a request must execute the middleware
422+
# and return a successful response http 200 status code
423+
result = app(API_REST_EVENT, {})
424+
425+
assert result["statusCode"] == 200
426+
427+
400428
@pytest.mark.parametrize(
401429
"app, event",
402430
[

0 commit comments

Comments
 (0)