Generates PHP 8.4 idempotency handler: PSR-15 middleware with Redis deduplication, IdempotencyKey value object, storage interface, exceptions, and unit tests for safe API retries.
From accnpx claudepluginhub dykyi-roman/awesome-claude-code --plugin accThis skill uses the workspace's default tool permissions.
references/examples.mdreferences/templates.mdCreates idempotency handling infrastructure for safe request deduplication.
| Scenario | Example |
|---|---|
| Payment processing | Prevent duplicate charges on retry |
| Order creation | Avoid duplicate orders from network retries |
| Webhook handling | Deduplicate incoming webhook deliveries |
| API mutations | Ensure POST/PUT/PATCH safety on retry |
Idempotency-Key HTTP headerexists(), store(), get(), remove()Path: src/Infrastructure/Idempotency/
IdempotencyKey.php — Value Object with UUID validationIdempotencyException.php — Duplicate request exceptionStoredResponse.php — Serializable response wrapperPath: src/Infrastructure/Idempotency/
IdempotencyStorageInterface.php — Storage contractRedisIdempotencyStorage.php — Redis SETNX + TTL implementationPath: src/Infrastructure/Idempotency/
IdempotencyMiddleware.php — PSR-15 middlewareIdempotencyKeyTest.php — Value Object validation testsIdempotencyMiddlewareTest.php — Middleware behavior tests| Component | Path |
|---|---|
| All Classes | src/Infrastructure/Idempotency/ |
| Unit Tests | tests/Unit/Infrastructure/Idempotency/ |
| Component | Pattern | Example |
|---|---|---|
| Value Object | IdempotencyKey | IdempotencyKey |
| Storage Interface | IdempotencyStorageInterface | IdempotencyStorageInterface |
| Redis Storage | RedisIdempotencyStorage | RedisIdempotencyStorage |
| Middleware | IdempotencyMiddleware | IdempotencyMiddleware |
| Response VO | StoredResponse | StoredResponse |
| Exception | IdempotencyException | IdempotencyException |
| Test | {ClassName}Test | IdempotencyKeyTest |
final readonly class IdempotencyKey
{
public function __construct(public string $value)
{
// Validates UUID v4 format
}
public static function fromHeader(string $headerValue): self;
public function toString(): string;
}
interface IdempotencyStorageInterface
{
public function exists(IdempotencyKey $key): bool;
public function store(IdempotencyKey $key, StoredResponse $response, int $ttl): void;
public function get(IdempotencyKey $key): ?StoredResponse;
public function remove(IdempotencyKey $key): void;
}
final readonly class IdempotencyMiddleware implements MiddlewareInterface
{
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface;
}
$middleware = new IdempotencyMiddleware(
storage: $redisStorage,
ttl: 86400,
headerName: 'Idempotency-Key'
);
// Client sends: POST /orders with header Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
// First request: processes and stores response
// Retry request: returns cached response immediately
Request ──→ Extract Idempotency-Key header
│
Key exists in storage?
│ │
YES NO
│ │
Return stored Process request
response │
Store response
│
Return response
| Anti-pattern | Problem | Solution |
|---|---|---|
| No TTL on keys | Storage grows unbounded | Set TTL (e.g., 24h) |
| In-memory storage | Lost on restart, no clustering | Use Redis or database |
| Idempotency on GET | GET is already idempotent | Only apply to mutations |
| Missing key validation | Accept invalid keys | Validate UUID format |
| No response caching | Cannot replay response | Store full response |
| Race conditions | Concurrent duplicates | Use SETNX atomic operation |
For complete PHP templates and examples, see:
references/templates.md — IdempotencyKey, StorageInterface, RedisStorage, Middleware templatesreferences/examples.md — API integration examples and testsProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.