Skip to main content

idempotency

Install, configure, and apply the Laravel Idempotency package in Laravel applications when you need retry-safe POST, PUT, or PATCH endpoints.

Ir a la instalación

Datos de origen

Repositorio
WendellAdriel/laravel-idempotency
Última actividad en el origen
14 de agosto de 2026 a las 15:32
Idioma detectado de SKILL.md
inglés
Estrellas
160
Forks
9

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
idempotency
description
Install, configure, and apply the Laravel Idempotency package in Laravel applications when you need retry-safe POST, PUT, or PATCH endpoints.
# Idempotency Use this skill when a Laravel application needs retry-safe write requests, idempotency keys, or controller attributes. ## Primary Goal - install and configure `wendelladriel/laravel-idempotency` correctly - choose the smallest correct integration path for the app - apply middleware, attributes, key inputs, and scopes using the package's public API ## Workflow ### 1. Inspect the Laravel app context - confirm the app is a Laravel project - inspect the target routes or controllers that create or update data - identify whether the endpoint is better served by route middleware or a controller attribute - inspect the app cache driver before enabling idempotency, since it must support atomic locks and be shared by every application server ### 2. Install and publish configuration when needed - install the package with `composer require wendelladriel/laravel-idempotency` - publish the config with `php artisan vendor:publish --tag=idempotency-config` when the app needs non-default behavior - use these config keys when customization is required: - `idempotency.ttl` - `idempotency.required` - `idempotency.scope` - `idempotency.header` - `idempotency.input` - `idempotency.strict_index_locks` ### 3. Choose the integration style Prefer route middleware when: - only a few endpoints need idempotency - the behavior belongs directly on a route definition - the app already configures most middleware in the route files Use the controller attribute when: - the app groups related write actions inside a controller - class-level defaults with method-level overrides make the intent clearer - `only` or `except` targeting is useful ### 4. Apply route middleware Use the package middleware class: ```php use WendellAdriel\Idempotency\Http\Middleware\Idempotent; Route::post('/orders', StoreOrderController::class) ->middleware(Idempotent::class); ``` When the endpoint needs overrides, use `Idempotent::using(...)`: ```php Route::post('/payments', ChargePaymentController::class) ->middleware(Idempotent::using( ttl: 600, required: false, scope: \WendellAdriel\Idempotency\Enums\IdempotencyScope::Ip, header: 'X-Idempotency-Key', )); ``` The package reads the key from the configured header first. When the header does not contain a non-empty string, it falls back to the configured request input, which defaults to `_idempotency_key`. Use the request input for standard HTML forms that cannot set custom headers. Use the `@idempotency` Blade directive to render the configured hidden input with a generated key: ```blade <form method="POST" action="/orders"> @csrf @idempotency </form> ``` Pass an existing key with `@idempotency($key)` when the application generates or stores the key elsewhere. ### 5. Apply the controller attribute Use the package attribute on classes or methods: ```php use WendellAdriel\Idempotency\Attributes\Idempotent; #[Idempotent] class OrderController { public function store() { // ... } } ``` Use method-level attributes to override class-level defaults: ```php use WendellAdriel\Idempotency\Enums\IdempotencyScope; #[Idempotent] class PaymentController { #[Idempotent(ttl: 600, scope: IdempotencyScope::Global)] public function store() { // ... } } ``` ### 6. Choose the correct scope - use `user` when authenticated users should not collide with each other; guests fall back to IP - use `ip` for guest-heavy flows where IP segmentation is enough - use `global` when the same key should replay across users or IPs ### 7. Support key generation - generate a random key in app code with `WendellAdriel\Idempotency\Idempotency::key()` when the server needs to create keys ### 8. Verify the integration - verify repeated `POST`, `PUT`, or `PATCH` requests with the same key replay the original response - verify mismatched payloads return `422` - verify in-flight duplicate requests return `409` with `Retry-After: 1` - verify requests without a valid header or request-input key only pass through when `required` is disabled ### 9. Maintain cached entries Use the maintenance commands when debugging replay behavior, purging entries after a compromised key, or inspecting cache usage during incident response. - inspect cached entries with `php artisan idempotency:list` - filter listings by scope or identity when the cache is large: ```bash php artisan idempotency:list --scope=user --id=5 php artisan idempotency:list --scope=global php artisan idempotency:list --limit=20 ``` - purge entries when replay behavior is the wrong thing to keep: ```bash # remove everything (prompts unless --force is passed) php artisan idempotency:forget --all --force # scoped removal php artisan idempotency:forget --scope=user --id=5 --force php artisan idempotency:forget --scope=ip --id=1.2.3.4 --force php artisan idempotency:forget --scope=global --force # purge everything tied to a single client-provided key php artisan idempotency:forget --key=checkout-1 --force ``` ## Rules, References, and Templates Read before executing: - no additional resource files for this skill ## Examples - add idempotency to payment or order creation endpoints - protect retryable webhook receivers ## Anti-patterns - do not apply idempotency to read-only routes - do not suggest unsupported scope values beyond `user`, `ip`, and `global` - do not document package maintenance tasks here; keep the skill focused on package adoption in Laravel apps - do not assume every cache driver supports atomic locks without checking - do not use the `array` driver outside tests or single-process development
Ver en GitHub