@setu-ts/idempotency-plugin — replay keyed requests
Add it: setu add idempotency adds it and inserts IdempotencyPlugin() into a recognized
functional setu.config.ts. It provides CAPABILITIES.IDEMPOTENCY (IIdempotencyService).
Replay a retried payment request
Authentication must establish a principal first. List this middleware after the route’s guards and validation:
import type { IRouterApi } from '@setu-ts/common';
import { idempotent } from '@setu-ts/idempotency-plugin';
export function registerPaymentRoutes(router: IRouterApi): void {
router.post('/payments', {
middleware: [idempotent({ required: true })],
handler: (ctx) => ctx.response.status(201).json({ id: 'pay-1' }),
});
}
Behaviour the types do not show
- The default key comes from the Idempotency-Key header. Missing required keys answer 400 after the principal check; missing principals answer 401 by default.
- A key with a different fingerprint answers 422; an active claim answers 409.
leaseMsandttlMsare milliseconds, defaulting to 60000 and 86400000 for HTTP.- The default memory store is process-local; it cannot coordinate replicas. A completed record suppresses repeat processing only within the store’s retention and claim limits.
- Place
idempotent()last: rejected guards or validation must not consume the key.
Other options
storeselects memory, Redis (type: 'redis',namespace,urlorclient) or a custom store.required: falsepasses unkeyed requests;response: 'status'retains no body or headers.idempotentIngress({ topics, jobNames })builds a factory for the host’sbehaviorsarray; work outside its allow-list passes through.withinneedstransactional: { store }to commit work and its idempotency record together.