Course contentsShow
← Node.js
Lesson 708 of 1,9807. Web Framework Architecture and MiddlewareFree lesson

Idempotent Operation Design

Implement middleware to ensure retried requests do not cause side effects in the system.

In this lesson, you will learn how to use middleware to track request identifiers, ensuring that retried operations don't trigger duplicate side effects in your system.

The Problem of Retries

In distributed systems, networks occasionally drop connections. A client might send a payment request, the server processes it, but the acknowledgment gets lost. The client, assuming the request failed, retries it. If you don't design for idempotency, you might charge your customer twice!

Implementing Idempotent Middleware

An idempotent operation is one that can be called multiple times with the same input without changing the result beyond the initial application. To enforce this, we use an Idempotency Key.

When a client sends a request, they provide a unique X-Idempotency-Key header. Our middleware intercepts this, checks a fast-access store (like Redis), and determines if we’ve already processed that specific key.

const idempotencyMiddleware = async (req, res, next) => {
  const key = req.headers['x-idempotency-key'];
  if (!key) return next();

  const cachedResult = await redis.get(`idempotency:${key}`);
  
  if (cachedResult) {
    // Return the cached response instead of re-running the logic
    return res.status(200).json(JSON.parse(cachedResult));
  }

  // Intercept the response to store it if processing succeeds
  const originalSend = res.send;
  res.send = function (body) {
    redis.set(`idempotency:${key}`, body, 'EX', 86400); // Store for 24h
    return originalSend.apply(res, arguments);
  };
  
  next();
};

How it Works

  1. Verification: The middleware checks the X-Idempotency-Key against your data store.
  2. Short-Circuiting: If the key exists, it means the system already performed this action. The middleware returns the previous result immediately, preventing the downstream service layer from executing duplicate logic.
  3. Recording: If the key is new, the request proceeds. We override the response method to cache the result upon successful completion, ensuring the next retry with the same key receives the same outcome.

By managing state at the edge, you protect your core business logic from the unpredictable nature of network retries.

Key Takeaway: Use middleware to intercept unique request identifiers and cache their outcomes, ensuring that redundant requests yield identical results without repeating sensitive side effects.