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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs