JAVASCRIPT
Generate Idempotency Keys for Safe API Retries
Learn to generate unique, client-side idempotency keys (UUIDs) for API requests. This ensures that repeated requests, like payment submissions, are processed only once by the server.
function generateUUID() {
// Standard compliant UUID v4 generator
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
const r = Math.random() * 16 | 0,
v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
async function makeIdempotentRequest(url, options = {}, idempotencyKey = null) {
const finalIdempotencyKey = idempotencyKey || generateUUID();
const headers = {
'Content-Type': 'application/json',
'Idempotency-Key': finalIdempotencyKey, // Custom header for idempotency
...options.headers,
};
try {
const response = await fetch(url, { ...options, headers });
if (!response.ok) {
throw new Error(`API error: ${response.status} ${response.statusText}`);
}
return await response.json();
} catch (error) {
console.error('Idempotent request failed:', error);
throw error;
}
}
// Example Usage:
// When submitting an order, generate an idempotency key once and reuse it if retrying.
// const orderData = { amount: 100, currency: 'USD', items: [...] };
// const myOrderIdempotencyKey = generateUUID(); // Generate once per logical transaction
// // First attempt
// makeIdempotentRequest('/api/orders', {
// method: 'POST',
// body: JSON.stringify(orderData)
// }, myOrderIdempotencyKey)
// .then(data => console.log('Order placed successfully (first attempt):', data))
// .catch(error => {
// console.error('First attempt failed, retrying...', error);
// // If network error, client can safely retry with the SAME key
// makeIdempotentRequest('/api/orders', {
// method: 'POST',
// body: JSON.stringify(orderData)
// }, myOrderIdempotencyKey)
// .then(retryData => console.log('Order placed successfully (retry attempt):', retryData))
// .catch(retryError => console.error('Retry attempt also failed:', retryError));
// });
// Or for a non-retry scenario, it can generate automatically:
// makeIdempotentRequest('/api/notifications', {
// method: 'POST',
// body: JSON.stringify({ message: 'User signed up!' })
// })
// .then(data => console.log('Notification sent:', data))
// .catch(error => console.error('Notification failed:', error));
How it works: This JavaScript snippet provides a utility to generate Universally Unique Identifiers (UUIDs) and integrate them as 'Idempotency-Key' headers in API requests. An idempotency key ensures that a server processes the same request only once, even if it receives identical requests multiple times due to network retries or client-side issues. This is crucial for operations like creating charges or submitting orders, preventing duplicate transactions. The `makeIdempotentRequest` function generates a UUID by default or accepts a provided one, adding it to the request headers for the backend to handle.