-
Notifications
You must be signed in to change notification settings - Fork 0
Body parsing
The adapter handles request bodies in two modes, picked automatically per request.
Is req.body defined?
├─ Yes → use it as-is (body-parser middleware already handled parsing)
└─ No → stream req, enforce maxBodyBytes, JSON.parse the result
Most Express apps use the built-in express.json() parser for other routes. When req.body !== undefined, the adapter uses that value directly.
app.use(express.json({limit: '2mb'}));
app.use('/planets', createExpressAdapter(planets));In this mode the body parser's own size cap applies; the adapter's maxBodyBytes is not consulted. This keeps the body-size policy in one place (the middleware chain), which is usually what you want.
Advantages:
- One place to configure JSON parsing (including non-JSON content types if you need them).
- Other middleware downstream / upstream can inspect / transform the body.
- Consistent
req.bodyshape across all routes.
If no body parser is installed, the adapter consumes req (the raw Node IncomingMessage — Express's Request extends it) directly, enforces a byte cap, and JSON.parses the result. Rejected on cap overflow or malformed JSON.
app.use(createExpressAdapter(planets, {maxBodyBytes: 256 * 1024}));Useful when:
- Your app is small enough that a body parser isn't worth wiring.
- You want per-adapter body-size policy (e.g. a bulk-load endpoint accepts 16 MiB while everything else caps at 64 KiB).
- You want to stay zero-deps beyond what's strictly required.
Default cap: 1048576 (1 MiB).
| Condition | Status | code |
|---|---|---|
Body exceeds maxBodyBytes
|
413 |
PayloadTooLarge |
| Body is not valid JSON | 400 |
BadJsonBody |
| Body is missing required shape | 400 |
BadLoadBody |
BadLoadBody specifically fires on PUT /-load when the body isn't an array.
You can run multiple adapters with different body-cap policies:
app.use(express.json({limit: '256kb'})); // default for most routes
app.use('/planets', createExpressAdapter(planets)); // uses pre-parsed body (256 KiB cap)
app.use('/bulk', createExpressAdapter(bulk, { // but pre-parsed means the express.json cap applies —
maxBodyBytes: 16 * 1024 * 1024 // `maxBodyBytes` here is ignored as long as
}))); // express.json ran first.If you need per-route body-size policy, mount the bulk adapter before the global body parser, or scope the body parser to specific routes using app.use(path, middleware).
// Bulk route streams its own body (no express.json upstream → maxBodyBytes kicks in).
app.use('/bulk', createExpressAdapter(bulk, {maxBodyBytes: 16 * 1024 * 1024}));
// Everything else uses the shared parser.
app.use(express.json({limit: '256kb'}));
app.use('/planets', createExpressAdapter(planets));Some stream-parsers destroy the underlying socket when they see an over-cap body, to prevent the client from uploading more. This adapter does not — the socket needs to stay alive so Express can write the 413 response. Backpressure plus the aborted flag stop the reader from buffering; the response completes normally; the connection closes via the framework's standard response-end path.
The worst case is a few kernel-buffer bytes per over-sized request — negligible compared to letting the framework respond.
The stream reader is a small utility exposed under dynamodb-toolkit-express/read-body.js:
import {readJsonBody} from 'dynamodb-toolkit-express/read-body.js';
// Elsewhere in your Express app:
const body = await readJsonBody(req, 1024 * 1024);Normally you won't need this — the adapter handles it internally. It's exported so consumers can reuse the same cap-enforced JSON reader in unrelated routes or when writing their own middleware for edge cases.