Blog Detail


Make Endpoints idempotent with Replay Idempotency Middleware cover image

arrow_back Make Endpoints idempotent with Replay Idempotency Middleware

Replay - Idempotency Middleware package makes your endpoints idempotent easily. It has the following features.

  • Add support idempotency requests to your APIs easily by adding a middleware.
  • Works only for POST requests. Other endpoints are ignored.
  • Record and replay only successful(2xx) and server-side errors(5xx) responses, without touching your controller again.
  • it’s safe to retry, it doesn’t record the response with client-side errors (4xx).
  • To prevent accidental misuse of the cached responses, the request’s signature is validated to ensure that the cached response is returned using the same combination of Idempotency-Key and Request.
  • Concurrency protection using Laravel’s atomic locks to prevent race conditions.


You can install the package via composer:

composer require bvtterfly/replay

You can publish the config file with:

php artisan vendor:publish --tag="replay-config"

Optionally, you can publish the translations using

php artisan vendor:publish --tag="replay-translations"

Server Usage

The Bvtterfly\Replay\Replay-middleware must be registered in the kernel:


protected $routeMiddleware = [
  'replay' => \Bvtterfly\Replay\Replay,

Next, For idempotent an endpoint, apply replay middleware to it:

Route::post('/payments', function () {

Custom Policy

Reply use Policy to determine whether a request is idempotent and whether the response should be recorded. By default, Reply includes and uses StripePolicy Policy. To create your custom policy, you first need to implement the \Butterfly\Replay\Contracts\Policy contract:

use Illuminate\Http\Request;
use Illuminate\Http\Response;

interface Policy
    public function isIdempotentRequest(Request $request): bool;

    public function isRecordableResponse(Response $response): bool;

If you want to view an example implementation take a look at the StripePolicy class.

For using this policy, We can change the policy in the config file.

Client Usage

To perform an idempotent request, Client must provide an additional Idempotency-Key : header with a unique key to the request.

it is recommended to:

  • Use V4 UUIDs for the creation of the idempotency unique keys (e.g. 07cd2d27-e0dc-466f-8193-28453e9c3023).

Once Replay detects a key, it’ll look it up in cache-store. If found, it will serve the same response without hitting your controller action again.

If Replay can’t find the key, it attempts to acquire a cache lock and caches successful or server error responses. Still, if it can’t acquire the lock, another request with the same key is already in progress, then it will respond with the HTTP Conflict response status code.

For more details, please visit its documentation and source code on Github

Published at : 01-07-2022

Author : Rizwan Aslam
Rizwan Aslam

I am a highly results-driven professional with 12+ years of collective experience in the grounds of web application development especially in laravel, native android application development in java, and desktop application development in the dot net framework. Now managing a team of expert developers at Codebrisk.

Launch your project

Launch project