@idempotix/next
v1.0.3
Published
Next.js integration for Idempotix idempotency
Maintainers
Readme
@idempotix/next
Next.js integration for HTTP idempotency. Supports App Router and Pages Router.
Installation
npm install @idempotix/core @idempotix/nextApp Router
// app/api/orders/route.ts
import { next } from '@idempotix/next';
export const POST = next()(async (req) => {
const order = await createOrder(await req.json());
return Response.json(order, { status: 201 });
});Pages Router
// pages/api/orders.ts
import { pages } from '@idempotix/next/pages';
export default pages()(async (req, res) => {
const order = await createOrder(req.body);
res.status(201).json(order);
});Configuration
Both next() and pages() accept the same options:
export const POST = next({
storage: upstash(), // Storage adapter
ttl: '1h', // Cache duration
required: true, // Require Idempotency-Key header
failOpen: true, // Continue if storage fails
getKey: (req) => req.headers.get('x-request-id'), // Custom key extraction
getHash: async (req) => hashObject(await req.json()), // Custom hash
onHit: (key, response) => {}, // Cache hit callback
onMiss: (key) => {}, // Cache miss callback
onError: (key, error) => {}, // Error callback
})(handler);Pre-configured Factory
Share configuration across routes:
// lib/idempotency.ts
import { configure } from '@idempotix/next';
import { upstash } from '@idempotix/upstash';
export const idempotent = configure({
storage: upstash(),
ttl: '1h',
});
// app/api/orders/route.ts
import { idempotent } from '@/lib/idempotency';
export const POST = idempotent()(handler);Pages Router has its own configure:
// lib/idempotency.ts
import { configure } from '@idempotix/next/pages';
export const idempotent = configure({
storage: upstash(),
ttl: '1h',
});
// pages/api/orders.ts
import { idempotent } from '@/lib/idempotency';
export default idempotent()(handler);Headers
| Header | Direction | Description |
| -------------------- | --------- | ------------------------------------- |
| Idempotency-Key | Request | Client-provided unique key |
| Idempotency-Key | Response | Echo of the key used |
| Idempotency-Replay | Response | true when returning cached response |
Error Responses
All errors follow RFC 7807 Problem Details:
| Status | Type | Cause |
| ------ | -------------- | ----------------------------------- |
| 400 | key-required | Missing key when required: true |
| 409 | conflict | Request with same key in progress |
| 422 | mismatch | Same key reused with different body |
With Upstash (Serverless)
import { upstash } from '@idempotix/upstash';
export const POST = next({ storage: upstash() })(handler);License
MIT
