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.
Installation
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:
//app/Http/Kernel.php
protected $routeMiddleware = [
...
'replay' => \Bvtterfly\Replay\Replay,
];
Next, For idempotent an endpoint, apply replay middleware to it:
Route::post('/payments', function () {
//
})->middleware('replay');
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 :
it is recommended to:
- Use
V4 UUIDsfor 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