You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/features/event-handler/http.md
+124-4Lines changed: 124 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,7 +9,7 @@ Event handler for Amazon API Gateway REST and HTTP APIs, Application Loader Bala
9
9
## Key Features
10
10
11
11
* Lightweight routing to reduce boilerplate for API Gateway REST/HTTP API, ALB and Lambda Function URLs.
12
-
* Built-in middleware engine for request/response transformation (validation coming soon).
12
+
* Built-in middleware engine for request/response transformation and validation.
13
13
* Works with micro function (one or a few routes) and monolithic functions (see [Considerations](#considerations)).
14
14
15
15
## Getting started
@@ -92,6 +92,26 @@ For your convenience, when you return a JavaScript object from your route handle
92
92
!!! tip "Automatic response format transformation"
93
93
The event handler automatically ensures the correct response format is returned based on the event type received. For example, if your handler returns an API Gateway v1 proxy response but processes an ALB event, we'll automatically transform it into an ALB-compatible response. This allows you to swap integrations with little to no code changes.
94
94
95
+
If you need to control the status code or headers alongside auto-serialization, return an object with `statusCode` and `headers` fields. The `body` field accepts any JSON-serializable value — object or array — and is automatically serialized. Omitting `body` produces an empty response body, which is useful for responses like `204 No Content`.
You can use `/todos/:todoId` to configure dynamic URL paths, where `:todoId` will be resolved at runtime.
@@ -182,11 +202,111 @@ If you prefer to use the decorator syntax, you can use the same methods on a cla
182
202
183
203
### Data validation
184
204
185
-
!!! note "Coming soon"
205
+
Event Handler supports built-in request and response validation using [Standard Schema](https://standardschema.dev){target="_blank"}, a common specification supported by popular TypeScript validation libraries including [Zod](https://zod.dev){target="_blank"}, [Valibot](https://valibot.dev){target="_blank"}, and [ArkType](https://arktype.io){target="_blank"}.
206
+
207
+
!!! note "Body validation is limited to JSON-serializable values"
208
+
Standard Schema validators operate on JavaScript values, not raw bytes. For body validation, Event Handler deserializes the body before passing it to your schema: `application/json` content is parsed as an object, all other content types are passed as a plain string. Binary data, streams, and other non-serializable response types cannot be validated.
209
+
210
+
#### Validating requests
211
+
212
+
Pass a `validation` option to your route handler with a `req` configuration to validate the incoming request. Validation runs before your handler, and if it fails, Event Handler automatically returns a **422 Unprocessable Entity** response with structured error details.
213
+
214
+
Validated data is available via `reqCtx.valid.req` and is fully typed based on your schema. Only the fields you provide schemas for are accessible: accessing an unvalidated field (e.g., `reqCtx.valid.req.headers` when no headers schema was configured) is a compile-time error.
1. Query params are always strings — `z.coerce.number()` coerces and validates the value, typing it as `number`
251
+
2. Validated path parameters available via `reqCtx.valid.req.path`
252
+
3. `page` and `limit` are typed as `number` — no manual casting needed
253
+
4. Validated headers available via `reqCtx.valid.req.headers`
254
+
5. Headers are always strings — `z.coerce.number()` coerces and validates the value, typing it as `number`
255
+
256
+
#### Validating responses
257
+
258
+
Pass a `validation` option to your route handler with a `res` configuration to validate the outgoing response body and headers after your handler executes. If validation fails, Event Handler returns a **500 Internal Server Error**.
259
+
260
+
Response validation is useful for ensuring your handler returns the expected shape and catching contract violations early.
261
+
Validated data is available via `reqCtx.valid.res` and is fully typed based on your schema. Only the fields you provide schemas
262
+
for are accessible: accessing an unvalidated field (e.g., `reqCtx.valid.res.headers` when no headers schema was configured) is a compile-time error.
You can also validate response headers by providing a `headers` schema in the `res` configuration. This is useful for enforcing that required headers — such as correlation IDs or cache directives — are always present:
1. Enforce that the correlation ID is a valid UUID
287
+
2. If either required header is absent or invalid, a 500 is returned
288
+
3. Headers are always strings — `z.coerce.number()` coerces and validates the value, typing it as `number`
289
+
290
+
You can combine both request and response validation in a single route by providing both `req` and `res`:
186
291
187
-
We plan to add built-in support for request and response validation using [Standard Schema](https://standardschema.dev){target="_blank"} in a future release. For the time being, you can use any validation library of your choice in your route handlers or middleware.
1. Access the validated and typed request body via `reqCtx.valid.req.body`
299
+
2. If the response doesn't match the schema, a 500 is returned
300
+
301
+
!!! tip
302
+
If you need request validation but want to skip runtime response validation, annotate your handler's return type directly and TypeScript will enforce the return shape at compile time:
Please [check this issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/4516) for more details and examples, and add 👍 if you would like us to prioritize it.
308
+
1. TypeScript enforces `Todo` as the return type at compile time
309
+
2. Only request validation runs at runtime — no response validation
0 commit comments