Skip to content

Commit 8862e69

Browse files
kmkhrheitorlessa
andauthored
fix(apigateway): support nested router decorators (#1709)
Co-authored-by: heitorlessa <[email protected]>
1 parent 053baef commit 8862e69

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

aws_lambda_powertools/event_handler/api_gateway.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,7 @@ def register_route(func: Callable):
798798
# Convert methods to tuple. It needs to be hashable as its part of the self._routes dict key
799799
methods = (method,) if isinstance(method, str) else tuple(method)
800800
self._routes[(rule, methods, cors, compress, cache_control)] = func
801+
return func
801802

802803
return register_route
803804

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
{
2+
"version": "1.0",
3+
"resource": "/my/anotherPath",
4+
"path": "/my/anotherPath",
5+
"httpMethod": "GET",
6+
"headers": {
7+
"Header1": "value1",
8+
"Header2": "value2"
9+
},
10+
"multiValueHeaders": {
11+
"Header1": [
12+
"value1"
13+
],
14+
"Header2": [
15+
"value1",
16+
"value2"
17+
]
18+
},
19+
"queryStringParameters": {
20+
"parameter1": "value1",
21+
"parameter2": "value"
22+
},
23+
"multiValueQueryStringParameters": {
24+
"parameter1": [
25+
"value1",
26+
"value2"
27+
],
28+
"parameter2": [
29+
"value"
30+
]
31+
},
32+
"requestContext": {
33+
"accountId": "123456789012",
34+
"apiId": "id",
35+
"authorizer": {
36+
"claims": null,
37+
"scopes": null
38+
},
39+
"domainName": "id.execute-api.us-east-1.amazonaws.com",
40+
"domainPrefix": "id",
41+
"extendedRequestId": "request-id",
42+
"httpMethod": "GET",
43+
"identity": {
44+
"accessKey": null,
45+
"accountId": null,
46+
"caller": null,
47+
"cognitoAuthenticationProvider": null,
48+
"cognitoAuthenticationType": null,
49+
"cognitoIdentityId": null,
50+
"cognitoIdentityPoolId": null,
51+
"principalOrgId": null,
52+
"sourceIp": "192.168.0.1/32",
53+
"user": null,
54+
"userAgent": "user-agent",
55+
"userArn": null,
56+
"clientCert": {
57+
"clientCertPem": "CERT_CONTENT",
58+
"subjectDN": "www.example.com",
59+
"issuerDN": "Example issuer",
60+
"serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
61+
"validity": {
62+
"notBefore": "May 28 12:30:02 2019 GMT",
63+
"notAfter": "Aug 5 09:36:04 2021 GMT"
64+
}
65+
}
66+
},
67+
"path": "/my/anotherPath",
68+
"protocol": "HTTP/1.1",
69+
"requestId": "id=",
70+
"requestTime": "04/Mar/2020:19:15:17 +0000",
71+
"requestTimeEpoch": 1583349317135,
72+
"resourceId": null,
73+
"resourcePath": "/my/anotherPath",
74+
"stage": "$default"
75+
},
76+
"pathParameters": null,
77+
"stageVariables": null,
78+
"body": "Hello from Lambda!",
79+
"isBase64Encoded": true
80+
}

tests/functional/event_handler/test_api_gateway.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,3 +1535,46 @@ def test_include_router_merges_context():
15351535
app.include_router(router)
15361536

15371537
assert app.context == router.context
1538+
1539+
1540+
def test_nested_app_decorator():
1541+
# GIVEN a Http API V1 proxy type event
1542+
# with a function registered with two distinct routes
1543+
app = APIGatewayRestResolver()
1544+
1545+
@app.get("/my/path")
1546+
@app.get("/my/anotherPath")
1547+
def get_lambda() -> Response:
1548+
return Response(200, content_types.APPLICATION_JSON, json.dumps({"foo": "value"}))
1549+
1550+
# WHEN calling the event handler
1551+
result = app(LOAD_GW_EVENT, {})
1552+
result2 = app(load_event("apiGatewayProxyEventAnotherPath.json"), {})
1553+
1554+
# THEN process event correctly
1555+
# AND set the current_event type as APIGatewayProxyEvent
1556+
assert result["statusCode"] == 200
1557+
assert result2["statusCode"] == 200
1558+
1559+
1560+
def test_nested_router_decorator():
1561+
# GIVEN a Http API V1 proxy type event
1562+
# with a function registered with two distinct routes
1563+
app = APIGatewayRestResolver()
1564+
router = Router()
1565+
1566+
@router.get("/my/path")
1567+
@router.get("/my/anotherPath")
1568+
def get_lambda() -> Response:
1569+
return Response(200, content_types.APPLICATION_JSON, json.dumps({"foo": "value"}))
1570+
1571+
app.include_router(router)
1572+
1573+
# WHEN calling the event handler
1574+
result = app(LOAD_GW_EVENT, {})
1575+
result2 = app(load_event("apiGatewayProxyEventAnotherPath.json"), {})
1576+
1577+
# THEN process event correctly
1578+
# AND set the current_event type as APIGatewayProxyEvent
1579+
assert result["statusCode"] == 200
1580+
assert result2["statusCode"] == 200

0 commit comments

Comments
 (0)