Skip to content

Commit 2da4094

Browse files
committed
Updated documentation
1 parent 552eb12 commit 2da4094

File tree

5 files changed

+138
-87
lines changed

5 files changed

+138
-87
lines changed

aidlc-docs/audit.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,3 +1537,60 @@ app.post('/users', handler, {
15371537
**Status**: Complete - all tests use spies to verify validation execution
15381538

15391539
---
1540+
1541+
## Update Examples and Documentation
1542+
**Timestamp**: 2025-11-11T20:52:47.478Z
1543+
**User Input**: "Update the changes made in examples/snippets/event-handler/rest with the latest. Update the docs in docs/features/event-handler/rest.md"
1544+
**AI Response**: Updating examples and documentation for validation feature
1545+
**Context**: Adding validation examples and documentation
1546+
1547+
---
1548+
1549+
## Examples and Documentation Updated
1550+
**Timestamp**: 2025-11-11T20:55:00.000Z
1551+
**AI Response**: Successfully updated examples and documentation for validation feature
1552+
**Context**: Updated to use new validation option API instead of middleware
1553+
1554+
**Changes Made**:
1555+
1. ✅ Updated `validation_basic.ts` - Use validation option instead of middleware
1556+
2. ✅ Updated `validation_query_headers.ts` - Use validation option
1557+
3. ✅ Updated `validation_error_handling.ts` - Use validation option
1558+
4. ✅ Updated `validation_README.md` - Document new API and configuration
1559+
5. ✅ Updated `docs/features/event-handler/rest.md` - Replace "coming soon" with full documentation
1560+
6. ✅ Added validation section with examples and supported libraries
1561+
1562+
**Documentation Sections Added**:
1563+
- Basic validation with Zod
1564+
- Validating multiple components
1565+
- Error handling
1566+
- Supported schema libraries table
1567+
- Development mode details
1568+
1569+
**Status**: Complete - examples and documentation updated with new validation API
1570+
1571+
---
1572+
1573+
## Fix Examples - Use Experimental Import
1574+
**Timestamp**: 2025-11-11T21:02:08.057Z
1575+
**User Input**: "Still use '@aws-lambda-powertools/event-handler/experimental-rest' for imports. Remove the validation_README.md file, the snippets folder only contains code snippets. Remove the part about customizing error using `onError`, it doesn't exist. Remove the part about supported schema libraries, development mode."
1576+
**AI Response**: Fixing examples to use experimental import and removing unnecessary content
1577+
**Context**: Simplifying examples and documentation
1578+
1579+
---
1580+
1581+
## Examples and Docs Fixed
1582+
**Timestamp**: 2025-11-11T21:03:00.000Z
1583+
**AI Response**: Fixed examples to use experimental import and simplified documentation
1584+
**Context**: Removed unnecessary content, kept only code snippets
1585+
1586+
**Changes Made**:
1587+
1. ✅ Updated all examples to use `@aws-lambda-powertools/event-handler/experimental-rest`
1588+
2. ✅ Removed `validation_README.md` file
1589+
3. ✅ Removed `onError` customization section from docs (doesn't exist)
1590+
4. ✅ Removed supported schema libraries table from docs
1591+
5. ✅ Removed development mode section from docs
1592+
6. ✅ Simplified validation_error_handling.ts to just show schema usage
1593+
1594+
**Status**: Complete - examples use experimental import, documentation simplified
1595+
1596+
---

docs/features/event-handler/http.md

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,42 @@ If you need to accept multiple HTTP methods in a single function, or support an
169169

170170
### Data validation
171171

172-
!!! note "Coming soon"
172+
You can validate incoming requests and outgoing responses using any schema library that implements the [Standard Schema](https://standardschema.dev){target="_blank"} specification, such as Zod, Valibot, or ArkType.
173+
174+
The validation feature automatically validates request components (body, headers, path parameters, query parameters) before your handler executes, and optionally validates responses after your handler completes.
175+
176+
#### Basic validation
177+
178+
Use the `validation` option when defining routes to specify which components to validate:
179+
180+
=== "validation_basic.ts"
181+
182+
```typescript hl_lines="17 20-22 26-31"
183+
--8<-- "examples/snippets/event-handler/rest/validation_basic.ts"
184+
```
185+
186+
#### Validating multiple components
173187

174-
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.
188+
You can validate multiple request components simultaneously:
175189

176-
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.
190+
=== "validation_query_headers.ts"
191+
192+
```typescript hl_lines="40-51"
193+
--8<-- "examples/snippets/event-handler/rest/validation_query_headers.ts"
194+
```
195+
196+
#### Error handling
197+
198+
Validation errors are automatically handled by the router:
199+
200+
- **Request validation failures** return HTTP 422 (Unprocessable Entity) with `RequestValidationError`
201+
- **Response validation failures** return HTTP 500 (Internal Server Error) with `ResponseValidationError`
202+
203+
=== "validation_error_handling.ts"
204+
205+
```typescript hl_lines="6-10"
206+
--8<-- "examples/snippets/event-handler/rest/validation_error_handling.ts"
207+
```
177208

178209
### Accessing request details
179210

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest';
2-
import { validation } from '@aws-lambda-powertools/event-handler/experimental-rest/middleware';
32
import { z } from 'zod';
43

54
const app = new Router();
@@ -19,40 +18,32 @@ const userResponseSchema = z.object({
1918
});
2019

2120
// Validate request body
22-
app.post('/users', {
23-
middleware: [validation({ req: { body: createUserSchema } })],
24-
}, async (reqCtx) => {
25-
const body = reqCtx.req.body;
26-
// body is typed as { name: string; email: string; age?: number }
27-
21+
app.post('/users', async () => {
2822
return {
29-
statusCode: 201,
30-
body: {
31-
id: '123',
32-
name: body.name,
33-
email: body.email,
34-
createdAt: new Date().toISOString(),
35-
},
23+
id: '123',
24+
name: 'John Doe',
25+
email: 'john@example.com',
26+
createdAt: new Date().toISOString(),
3627
};
28+
}, {
29+
validation: { req: { body: createUserSchema } },
3730
});
3831

3932
// Validate both request and response
40-
app.get('/users/:id', {
41-
middleware: [validation({
42-
req: { path: z.object({ id: z.string().uuid() }) },
43-
res: { body: userResponseSchema },
44-
})],
45-
}, async (reqCtx) => {
33+
app.get('/users/:id', async (reqCtx) => {
4634
const { id } = reqCtx.params;
4735

4836
return {
49-
body: {
50-
id,
51-
name: 'John Doe',
52-
email: 'john@example.com',
53-
createdAt: new Date().toISOString(),
54-
},
37+
id,
38+
name: 'John Doe',
39+
email: 'john@example.com',
40+
createdAt: new Date().toISOString(),
5541
};
42+
}, {
43+
validation: {
44+
req: { path: z.object({ id: z.string().uuid() }) },
45+
res: { body: userResponseSchema },
46+
},
5647
});
5748

5849
export const handler = app.resolve.bind(app);
Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,23 @@
1-
import { Router, RequestValidationError } from '@aws-lambda-powertools/event-handler/experimental-rest';
2-
import { validation } from '@aws-lambda-powertools/event-handler/experimental-rest/middleware';
1+
import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest';
32
import { z } from 'zod';
43

54
const app = new Router();
65

7-
// Custom error handler for validation errors
8-
app.onError(RequestValidationError, (error) => {
9-
return {
10-
statusCode: 422,
11-
body: {
12-
error: 'Validation Failed',
13-
message: error.message,
14-
component: error.component,
15-
// In development, include detailed validation errors
16-
...(process.env.POWERTOOLS_DEV === 'true' && {
17-
details: error.details,
18-
}),
19-
},
20-
};
21-
});
22-
236
const userSchema = z.object({
247
name: z.string().min(1, 'Name is required'),
258
email: z.string().email('Invalid email format'),
269
age: z.number().int().positive('Age must be positive'),
2710
});
2811

29-
app.post('/users', {
30-
middleware: [validation({ req: { body: userSchema } })],
31-
}, async (reqCtx) => {
32-
const body = reqCtx.req.body;
33-
12+
app.post('/users', async () => {
3413
return {
35-
statusCode: 201,
36-
body: { id: '123', ...body },
14+
id: '123',
15+
name: 'John Doe',
16+
email: 'john@example.com',
17+
age: 30,
3718
};
19+
}, {
20+
validation: { req: { body: userSchema } },
3821
});
3922

4023
export const handler = app.resolve.bind(app);
Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest';
2-
import { validation } from '@aws-lambda-powertools/event-handler/experimental-rest/middleware';
32
import { z } from 'zod';
43

54
const app = new Router();
@@ -11,22 +10,16 @@ const listUsersQuerySchema = z.object({
1110
sort: z.enum(['name', 'email', 'createdAt']).optional(),
1211
});
1312

14-
app.get('/users', {
15-
middleware: [validation({ req: { query: listUsersQuerySchema } })],
16-
}, async (reqCtx) => {
17-
const url = new URL(reqCtx.req.url);
18-
const query = Object.fromEntries(url.searchParams.entries());
19-
// query is typed with validated schema
20-
13+
app.get('/users', async () => {
2114
return {
22-
body: {
23-
users: [],
24-
pagination: {
25-
page: query.page || 1,
26-
limit: query.limit || 10,
27-
},
15+
users: [],
16+
pagination: {
17+
page: 1,
18+
limit: 10,
2819
},
2920
};
21+
}, {
22+
validation: { req: { query: listUsersQuerySchema } },
3023
});
3124

3225
// Validate headers
@@ -35,15 +28,23 @@ const apiKeyHeaderSchema = z.object({
3528
'content-type': z.string().optional(),
3629
});
3730

38-
app.post('/protected', {
39-
middleware: [validation({ req: { headers: apiKeyHeaderSchema } })],
40-
}, async () => {
41-
return { statusCode: 200, body: 'Access granted' };
31+
app.post('/protected', async () => {
32+
return { message: 'Access granted' };
33+
}, {
34+
validation: { req: { headers: apiKeyHeaderSchema } },
4235
});
4336

4437
// Validate multiple components
45-
app.post('/users/:id/posts', {
46-
middleware: [validation({
38+
app.post('/users/:id/posts', async (reqCtx) => {
39+
const { id } = reqCtx.params;
40+
41+
return {
42+
postId: '456',
43+
userId: id,
44+
title: 'New Post',
45+
};
46+
}, {
47+
validation: {
4748
req: {
4849
path: z.object({ id: z.string().uuid() }),
4950
body: z.object({
@@ -54,19 +55,7 @@ app.post('/users/:id/posts', {
5455
'content-type': z.literal('application/json'),
5556
}),
5657
},
57-
})],
58-
}, async (reqCtx) => {
59-
const { id } = reqCtx.params;
60-
const body = reqCtx.req.body;
61-
62-
return {
63-
statusCode: 201,
64-
body: {
65-
postId: '456',
66-
userId: id,
67-
title: body.title,
68-
},
69-
};
58+
},
7059
});
7160

7261
export const handler = app.resolve.bind(app);

0 commit comments

Comments
 (0)