DEV Community

Caique Santos
Caique Santos

Posted on

Preventing duplicate requests with Idempotency

Introduction

Idempotency is a way to ensure that an operation is not executed multiple times with unintended side effects.

Consider this scenario: a client submits an order in your application, but due to a network issue, a double-click on the submit button, or even a malicious attempt to exploit your system, the same request is sent multiple times to your API. How should you handle this?

This is where idempotency comes into play. Below I'll show some strategies used to handle it.

Handling Idempotency in Frontend

There are a few strategies you can apply on the frontend to prevent duplicate requests from being sent, but the frontend alone is not enough to guarantee idempotency. Here are those strategies:

  • Disable the button immediately after the request is sent to the backend
  • Redirect the user to a success page after the request is completed
  • Generate an idempotency key and send it to the backend for proper handling

Handling Idempotency in Backend

To properly handle this issue on the backend, a clean and effective approach is to use middleware to intercept incoming requests and validate the idempotency key provided by the client. Below is an example in C#:

public class IdempotencyMiddleware {
    private readonly RequestDelegate _next;

    public IdempotencyMiddleware(RequestDelegate next) {
        _next = next;
    }

    public async Task Invoke(HttpContext context) {
        var key = context.Request.Headers["Idempotency-Key"].FirstOrDefault();

        if (string.IsNullOrEmpty(key)) {
            await _next(context);
            return;
        }

        // CODE BLOCK TO VERIFY THE IDEMPOTENCY

        await _next(context);
    }
}
Enter fullscreen mode Exit fullscreen mode

However, there are scenarios where an idempotency key provided by the frontend cannot be fully trusted. In such cases, the backend should generate or derive its own idempotency key to ensure consistency and reliability.

Handling Idempotency in Database

You can also enforce idempotency at the database level. Imagine a scenario where you have a form for creating a user. If your database is properly designed with the correct unique constraints, the same user cannot be stored more than once. For example:

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    email TEXT UNIQUE,
    name TEXT,
    ...
);
Enter fullscreen mode Exit fullscreen mode

In this example, the email field is defined as unique, so even if the system attempts to insert the same user multiple times, the database will prevent duplicates.

Conclusion

In summary, idempotency is essential to prevent duplicate operations and ensure system reliability. Whether handled on the frontend, backend, or database level, combining these approaches leads to a more robust and resilient application.

Top comments (0)