wendelladriel/laravel-idempotency
Add idempotency to Laravel routes with middleware that stores responses keyed by an idempotency header, preventing duplicate requests and making retries safe. Configurable storage and locking help protect payments, orders, and other critical operations.
Baseline note: no prior assessment existed for this package, so this evaluation is established from the v1.5.1 release and the package's publicly observable surface. v1.5.1 is a patch release with two changes, neither of which is a breaking change:
Exclude fallback input from request fingerprints (PR #21) — a behavioral fix in how the package derives the request fingerprint used to detect idempotency-key reuse with a different payload. Requests that resolve an input via a fallback/default path previously produced fingerprints that diverged from the equivalent explicit request, which could surface as spurious key-conflict errors. This is the only runtime-relevant change and it is a correctness narrowing, not a contract change.Bump actions/deploy-pages from 5.0.0 to 5.0.1 (PR #22) — CI/publishing only. Zero runtime surface.Architecture fit. The package is a cross-cutting HTTP middleware concern for Laravel: it wraps requests carrying an idempotency key, persists a record keyed by that key (plus fingerprint), and replays or blocks duplicates. This is a natural fit for Laravel's kernel/middleware pipeline and requires no framework forks, no service-provider overrides of core behaviour, and no changes to controller signatures. It belongs in the same architectural layer as rate limiting and request logging — infrastructure, not domain logic.
Integration feasibility. Low-to-moderate. A single composer require, optional config publish, optional migration (if a database-backed store is offered in addition to cache), and middleware registration on selected route groups. A competent Laravel engineer can have a working spike in under a day and a production-shaped pilot in one sprint. The real effort is not installation but agreeing the client contract: which header carries the key, who generates it, what the client does on a 409/422 conflict, and how long keys remain valid.
Technical risk.
has/put sequences, or on a store that does not honour distributed locks across nodes, degrades silently into "usually idempotent."Key questions to put to the maintainer or resolve in the spike:
input() defaults?Stack fit. Native to Laravel's HTTP layer; no other framework dependency is implied. Works alongside existing middleware ordering (place it after authentication and authorization so keys are scoped to an authenticated principal and unauthorized traffic never writes to the idempotency store, and before controllers so replays short-circuit business logic). No conflict with queued jobs, console commands, or event-driven paths — but note the package cannot protect those; idempotency for async consumers is a separate design problem and should be called out explicitly so nobody assumes coverage.
Migration path. Incremental, not big-bang. Treat it as an additive wrapper on a small set of non-idempotent write endpoints (payments, order creation, webhook ingestion, external side-effect triggers) and leave reads and naturally idempotent PUT/DELETE alone. Because v1.5.1 is a patch release with no API changes, adopting it directly is reasonable — there is no reason to land on 1.5.0 first.
Compatibility. The two things that actually gate this are (a) the cache/lock backend and its multi-node behaviour, and (b) whether the app runs under Octane or a load balancer, in which case an in-process or single-node store is unacceptable from day one. Pin the package version in composer.json and let Dependabot propose bumps rather than floating.
Sequencing.
Maintenance. Low code churn, moderate attention requirement. Expect frequent patch releases (this one is 12 days after 1.5.0 in pattern) that are safe but need a human to confirm they are CI-only versus behavioural. Assign a named owner; automate composer update in a branch with the idempotency test suite as the gate.
Support. No commercial backing and a small contributor pool — the realistic support model is "we read the source." Budget for the possibility of forking or vendoring. The package is small enough that a fork is a viable contingency, which materially reduces the risk of the single-maintainer profile.
Scaling. Cost scales with write traffic, not total traffic, and is dominated by store sizing rather than CPU. Two numbers to establish early: key cardinality per day and average stored response size. Together these set Redis memory or table growth and therefore the TTL you can afford. Multi-node correctness requires a shared store with real locking; a per-node cache is a silent correctness bug at scale, not a performance trade-off.
Failure modes to instrument.
Ramp-up. Genuinely small for a mid-level Laravel engineer: hours to understand the middleware, a day to own it. The harder ramp is organisational — client teams must adopt key generation and conflict handling correctly, and that is a documentation and SDK problem, not a PHP one. Allocate effort there; the v1.5.1 fingerprint fix is a good reminder that subtle payload-equivalence questions exist and are worth writing down for client authors.
How can I help you explore Laravel packages today?