-
Notifications
You must be signed in to change notification settings - Fork 0
Options
createExpressAdapter(adapter, options?) accepts an optional options object with the following shape:
interface ExpressAdapterOptions<TItem extends Record<string, unknown> = Record<string, unknown>> {
policy?: Partial<RestPolicy>;
sortableIndices?: Record<string, string>;
keyFromPath?: (rawKey: string, adapter: Adapter<TItem>) => Record<string, unknown>;
exampleFromContext?: (query: Record<string, string>, body: unknown, req: Request) => Record<string, unknown>;
maxBodyBytes?: number;
}All options are optional. The factory is generic in TItem so that typed Adapter<Planet, PlanetKey> flows through to keyFromPath's second argument without casts.
Partial overrides for the REST policy. Merged shallowly with defaultPolicy from dynamodb-toolkit/rest-core — only the fields you pass are touched.
createExpressAdapter(adapter, {
policy: {
defaultLimit: 25,
maxLimit: 500,
maxOffset: 10_000, // DoS cap on `?offset=` (since toolkit 3.1.1)
needTotal: false,
envelope: {items: 'rows', total: 'count', offset: 'skip', limit: 'take', links: 'links'},
metaPrefix: '$',
methodPrefix: '!',
statusCodes: {
miss: 410,
validation: 422,
consistency: 409,
throttle: 429,
transient: 503,
internal: 500
}
}
});See the parent wiki's REST core page for the full RestPolicy reference.
Maps the public sort-field name (?sort=field or ?sort=-field) to the GSI that provides that ordering. Without an entry, ?sort=… is ignored (no index set, no error).
createExpressAdapter(adapter, {
sortableIndices: {
name: 'by-name-index',
createdAt: 'by-created-index',
mass: 'by-mass-index'
}
});?sort=-createdAt then resolves to {index: 'by-created-index', descending: true} and is passed to the Adapter's list call.
Convert the URL :key path segment into a key object. Runs on every keyed route. Default:
(raw, adapter) => ({[adapter.keyFields[0].name]: raw})Overrides are the idiomatic place for composite keys, type coercion, and key-format validation:
// Composite "partition:sort" keys
createExpressAdapter(adapter, {
keyFromPath: raw => {
const [pk, sk] = raw.split(':');
if (!pk || !sk) {
throw Object.assign(new Error('Expected key of shape pk:sk'), {status: 400, code: 'BadKey'});
}
return {pk, sk};
}
});
// Numeric partition keys
createExpressAdapter(adapter, {
keyFromPath: (raw, a) => {
const n = Number(raw);
if (!Number.isFinite(n)) throw Object.assign(new Error('Numeric key expected'), {status: 400});
return {[a.keyFields[0].name]: n};
}
});The adapter is passed through so you can read adapter.keyFields when writing generic callbacks. See Composite keys for more patterns.
Build the example object passed to Adapter.prepareListInput(example, index). Runs on the collection-level routes that call the Adapter's list machinery: GET /, DELETE /, PUT /-clone, PUT /-move.
Signature:
(query, body, req) => exampleObjectDefault: () => ({}) — no example, prepareListInput derives everything from index alone.
createExpressAdapter(adapter, {
exampleFromContext: (query, _body, req) => ({
tenant: req.user.tenantId, // set by upstream auth middleware
status: query.status || 'active'
})
});The three args:
-
query— parsed URL query asRecord<string, string>. Nested-object values from Express'sqsparser are dropped; array values are collapsed to the first element. -
body— parsed request body,unknown. Only defined forPUT /-clone/PUT /-move, which have a body;nullonGET //DELETE /. -
req— the full ExpressRequest. Use it to pull auth info from upstream middleware (req.user), request metadata (req.headers,req.ip), etc.
See Per-tenant filtering for a complete cookbook.
Byte cap for raw request bodies. Only enforced when the adapter is streaming the body itself — i.e. when req.body is undefined. If a body-parser middleware (express.json() or equivalent) has already populated req.body, that parser's own cap applies.
Default: 1048576 (1 MiB), matching dynamodb-toolkit/handler.
// Low-power device endpoint — cap at 64 KiB
createExpressAdapter(adapter, {maxBodyBytes: 64 * 1024});
// Dedicated bulk-load endpoint — allow larger bodies
createExpressAdapter(bulkAdapter, {maxBodyBytes: 16 * 1024 * 1024});Over-cap requests are rejected with 413 PayloadTooLarge and {code: 'PayloadTooLarge'}. Malformed JSON gives 400 BadJsonBody.
See Body parsing for the full streaming / pre-parsed decision flow.
The options surface is a direct superset of dynamodb-toolkit/handler's HandlerOptions:
-
policy,sortableIndices,keyFromPath,maxBodyBytes— identical shape and semantics. -
exampleFromContext— extended from the core's(query, body)signature with a thirdreqargument. Callbacks written against the core handler still work (extra args ignored).