Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion docs/core/event_handler/api_gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,50 @@ Here's a sample middleware that extracts and injects correlation ID, using `APIG
--8<-- "examples/event_handler_rest/src/middleware_getting_started_output.json"
```

#### Accessing the Request object

After route resolution, Event Handler creates a `Request` object with the **resolved** route context. You can access it in two ways:

1. **`app.request`** - available in middleware functions.
2. **`request: Request` type annotation** - injected automatically into route handlers as a parameter.

`Request` gives you the resolved route context that `app.current_event` doesn't have:

| Property | Example | Description |
| --------------------- | ---------------------------------------- | ----------------------------------------------------- |
| `route` | `/todos/{todo_id}` | Matched route pattern in OpenAPI path-template format |
| `path_parameters` | `{"todo_id": "123"}` | Powertools-resolved path parameters |
| `method` | `GET` | HTTP method (upper-case) |
| `headers` | `{"content-type": "application/json"}` | Request headers |
| `query_parameters` | `{"page": "1"}` | Query string parameters |
| `body` | `'{"name": "task"}'` | Raw request body |
| `json_body` | `{"name": "task"}` | Deserialized request body |

=== "Using `app.request` in middleware"

```python hl_lines="10 13-15 21" title="Accessing Request via app.request"
--8<-- "examples/event_handler_rest/src/middleware_request_object.py"
```

1. Access the resolved `Request` object from the app instance.
2. `request.route` returns the matched route pattern, e.g. `/todos/{todo_id}`.
3. `request.path_parameters` returns the Powertools-resolved parameters, e.g. `{"todo_id": "123"}`.
4. You can include route metadata in the response headers.

=== "Using `request: Request` in route handlers"

```python hl_lines="7 10" title="Accessing Request via type annotation"
--8<-- "examples/event_handler_rest/src/middleware_request_handler_injection.py"
```

1. Add `request: Request` as a parameter - Event Handler injects it automatically.
2. Access resolved route, path parameters, headers, query parameters, and body.

???+ note "When to use `Request` vs `app.current_event`"
Use `Request` for **route-aware** logic like authorization, logging, and metrics - it gives you the matched route pattern and Powertools-resolved path parameters.

Use `app.current_event` when you need the **raw event** data like request context, stage variables, or authorizer context that is available from the start of the request, before route resolution.

#### Global middlewares

<figure markdown="span">
Expand Down Expand Up @@ -1112,7 +1156,7 @@ Keep the following in mind when authoring middlewares for Event Handler:
2. **Call the next middleware**. Return the result of `next_middleware(app)`, or a [Response object](#fine-grained-responses) when you want to [return early](#returning-early).
3. **Keep a lean scope**. Focus on a single task per middleware to ease composability and maintenance. In [debug mode](#debug-mode), we also print out the order middlewares will be triggered to ease operations.
4. **Catch your own exceptions**. Catch and handle known exceptions to your logic. Unless you want to raise [HTTP Errors](#raising-http-errors), or propagate specific exceptions to the client. To catch all and any exceptions, we recommend you use the [exception_handler](#exception-handling) decorator.
5. **Use context to share data**. Use `app.append_context` to [share contextual data](#sharing-contextual-data) between middlewares and route handlers, and `app.context.get(key)` to fetch them. We clear all contextual data at the end of every request.
5. **Use context to share data**. Use `app.append_context` to [share contextual data](#sharing-contextual-data) between middlewares and route handlers, and `app.context.get(key)` to fetch them. We clear all contextual data at the end of every request. For route-aware request data, use [`app.request`](#accessing-the-request-object) instead.

### Fine grained responses

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from aws_lambda_powertools.event_handler import APIGatewayRestResolver, Request

app = APIGatewayRestResolver()


@app.get("/todos/<todo_id>")
def get_todo(todo_id: str, request: Request): # (1)!
return {
"id": todo_id,
"route": request.route, # (2)!
"user_agent": request.headers.get("user-agent", ""),
}


def lambda_handler(event, context):
return app.resolve(event, context)
30 changes: 30 additions & 0 deletions examples/event_handler_rest/src/middleware_request_object.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from aws_lambda_powertools import Logger
from aws_lambda_powertools.event_handler import APIGatewayRestResolver, Response
from aws_lambda_powertools.event_handler.middlewares import NextMiddleware

app = APIGatewayRestResolver()
logger = Logger()


def request_context_middleware(app: APIGatewayRestResolver, next_middleware: NextMiddleware) -> Response:
request = app.request # (1)!

logger.append_keys(
route=request.route, # (2)!
method=request.method,
path_parameters=request.path_parameters, # (3)!
)

response = next_middleware(app)

response.headers["x-route-pattern"] = request.route # (4)!
return response


@app.get("/todos/<todo_id>", middlewares=[request_context_middleware])
def get_todo(todo_id: str):
return {"id": todo_id}


def lambda_handler(event, context):
return app.resolve(event, context)
25 changes: 11 additions & 14 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading