温德尔·阿德里尔
发布
Laravel Idempotency
, a package that adds HTTP idempotency to write-oriented Laravel routes. When a
POST
,
PUT
, 或者
PATCH
request is retried with the same idempotency key and the same payload, the package replays the original cached response instead of running the route handler again — a common requirement for payment endpoints, order creation, and any API where clients may retry on network failure.
Applying the Middleware
The package provides two ways to attach idempotency to a route. The first is a standard route middleware:
使用
WendellAdriel\Idempotency\Http\Middleware\Idempotent
;路线
::
邮政
(
'/orders'
,
StoreOrderController
::班级
)
->
中间件
(
同样强大
::班级
(英文):
The middleware expects an
Idempotency-Key
header. When the same key is sent again with identical request data, the original response is returned with an
Idempotency-Replayed: true
header added.
Per-route configuration is available via
Idempotent::using()
:
路线
::
邮政
(
'/payments'
,
ChargePaymentController
::班级
)
->
中间件
(
同样强大
::
使用
(
生存时间
:
600
,
lockTimeout
:
30
,
必需的
:
错误的
,
范围
:
\WendellAdriel\Idempotency\Enums\IdempotencyScope
::
Ip
,
标题
:
'X-Idempotency-Key'
,)(英文):
The second option is a PHP attribute, which works at the class or method level and accepts the same options:
使用
WendellAdriel\Idempotency\Attributes\Idempotent
;使用
WendellAdriel\Idempotency\Enums\IdempotencyScope
;#[
同样强大
]班级
支付控制器{#[
同样强大
(
生存时间
:
600
,
lockTimeout
:
30
,
范围
:
IdempotencyScope
::
Ip
)]
民众
功能
店铺
(){
// ...}}
Since the attribute extends Laravel's built-in controller middleware attribute,
only
和
except
work as expected.
Key Scoping
Idempotency keys can be scoped three ways, configured globally in
config/idempotency.php
or overridden per route:
| 范围 | 行为 |
|---|---|
user |
Keys are segmented by authenticated user; guest requests fall back to client IP |
ip |
Keys are segmented by client IP address |
global |
The same key applies across all users and IP addresses |
Conflict Detection
The package handles two conflict scenarios. If a request arrives with the same key but a different payload, it returns
422 Unprocessable Entity
. If a second matching request arrives while the first is still being processed — a true in-flight duplicate — it returns
409 Conflict
和
Retry-After: 1
header. Both behaviors work through Laravel's cache atomic locks, so a cache driver with lock support (Redis, Memcached) is required.
工匠指令
Two commands let you inspect and clear cached entries without touching the cache directly.
idempotency:list
renders a table of active entries with scope, identifier, key, route, status code, and expiry:
php
工匠
idempotency:list
--scope=user
--id=5
idempotency:forget
removes entries by scope, identifier, or key. Destructive calls prompt for confirmation unless
--force
is passed:
# remove all entries for a specific userphp
工匠
idempotency:forget
--scope=user
--id=5
- 力量# remove every entry for a given client-provided keyphp
工匠
idempotency:forget
--key=checkout-1
- 力量
You can find Laravel Idempotency on GitHub 。







