@idempotix/express
v1.0.3
Published
Express middleware for Idempotix idempotency
Downloads
8
Maintainers
Readme
@idempotix/express
Express middleware for HTTP idempotency.
Installation
npm install @idempotix/core @idempotix/expressQuick Start
import express from 'express';
import { express as idempotent } from '@idempotix/express';
const app = express();
app.use(express.json());
// Zero-config: memory storage, 24h TTL
app.post('/orders', idempotent(), async (req, res) => {
const order = await createOrder(req.body);
res.status(201).json(order);
});Configuration
app.post(
'/payments',
idempotent({
storage: redis(), // Storage adapter
ttl: '1h', // Cache duration
required: true, // Require Idempotency-Key header
methods: ['POST', 'PUT'], // HTTP methods to protect
failOpen: true, // Continue if storage fails
getKey: (req) => req.headers['x-request-id'], // Custom key extraction
getHash: (req) => hashObject(req.body), // Custom hash function
onHit: (key, response) => {}, // Cache hit callback
onMiss: (key) => {}, // Cache miss callback
onError: (key, error) => {}, // Error callback
}),
handler
);Pre-configured Factory
Share configuration across routes:
import { configure } from '@idempotix/express';
import { redis } from '@idempotix/redis';
const idempotent = configure({
storage: redis(),
ttl: '1h',
});
app.post('/orders', idempotent(), orderHandler);
app.post('/payments', idempotent({ required: true }), paymentHandler);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 |
{
"type": "https://Idempotix.dev/errors/conflict",
"title": "Conflict",
"status": 409,
"detail": "A request with this idempotency key is already being processed"
}With Redis
import { redis } from '@idempotix/redis';
app.post('/orders', idempotent({ storage: redis() }), handler);License
MIT
