Laravel Idempotency: middleware для идемпотентных HTTP-запросов

Вендэлл Адриэль представил пакет Laravel Idempotency, который добавляет поддержку идемпотентности для write-запросов в Laravel. При повторной отправке POST, PUT или PATCH с тем же ключом и тем же payload пакет возвращает закэшированный ответ вместо повторного выполнения обработчика. Это используется в сценариях с платежами, созданием заказов и других API, где возможны повторы из-за сетевых сбоев.

Подключение middleware

Пакет можно применить к маршруту через стандартный middleware:

use WendellAdriel\Idempotency\Http\Middleware\Idempotent;

Route::post('/orders', StoreOrderController::class)
    ->middleware(Idempotent::class);

Middleware ожидает заголовок Idempotency-Key. Если тот же ключ приходит повторно с идентичными данными, возвращается исходный ответ с дополнительным заголовком Idempotency-Replayed: true.

Настройки можно задать на уровне маршрута:

Route::post('/payments', ChargePaymentController::class)->middleware(
    Idempotent::using(
        ttl: 600,
        lockTimeout: 30,
        required: false,
        scope: \WendellAdriel\Idempotency\Enums\IdempotencyScope::Ip,
        header: 'X-Idempotency-Key',
    )
);

Также доступен вариант через PHP-атрибуты для класса или метода контроллера:

use WendellAdriel\Idempotency\Attributes\Idempotent;
use WendellAdriel\Idempotency\Enums\IdempotencyScope;

#[Idempotent]
class PaymentController
{
    #[Idempotent(ttl: 600, lockTimeout: 30, scope: IdempotencyScope::Ip)]
    public function store()
    {
        // ...
    }
}

Атрибут наследует поведение стандартных middleware Laravel, поэтому поддерживаются параметры only и except.

Область действия ключей

Ключи идемпотентности могут работать в разных областях, которые настраиваются глобально или для конкретного маршрута:

  • user - ключи разделяются по пользователям, для гостей используется IP

  • ip - разделение по IP-адресу

  • global - один ключ действует для всех пользователей и IP

Обработка конфликтов

Пакет обрабатывает два типа конфликтов. Если приходит тот же ключ, но с другим payload, возвращается ошибка 422 Unprocessable Entity.

Если второй идентичный запрос поступает до завершения первого, возвращается 409 Conflict с заголовком Retry-After: 1.

Обе ситуации реализованы через атомарные блокировки кеша, поэтому требуется драйвер с поддержкой lock, например Redis или Memcached.

Artisan-команды

Пакет добавляет команды для работы с кешированными записями. Просмотр активных записей:

php artisan idempotency:list --scope=user --id=5

Удаление записей:

# удалить все записи пользователя
php artisan idempotency:forget --scope=user --id=5 --force

# удалить записи по ключу
php artisan idempotency:forget --key=checkout-1 --force

Команда удаления требует подтверждения, если не указан флаг --force.

Похожие статьи

Рекомендательные технологии Подробнее
Технологии и IT-новости 4 месяца назад

Новая натрий-ионная батарея делает ставку на древесину

Новая натрий-ионная батарея, в которой в качестве ключевого материала используется лигнин — побочный продукт деревообработки. Технология обещает снизить стоимость аккумуляторов и уменьшить зависимость от дефицитных металлов.

Технологии и IT-новости 4 месяца назад

Tesla меняет курс: электромобили уступают место роботам и искусственному интеллекту

Tesla официально прекращает производство Model S и Model X, чтобы сосредоточиться на роботах-гуманоидах и ИИ-технологиях. Компания переориентирует завод во Фримонте под выпуск Optimus и усилит разработку автономных сервисов и продуктов.

Технологии и IT-новости 2 месяца назад

Firefox 149.0.2: улучшения панели инструментов в Wayland

Firefox 149.0.2 устраняет проблемы с панелью инструментов в Wayland, исправляет сбои WebAuthn и баги при печати страниц. Это небольшой стабильный релиз с фокусом на исправления.

Как ускорить Laravel-приложение: параллельные API-запросы через Http::pool и Http::batch

Статья объясняет, как ускорить Laravel-приложения, выполняя API-запросы параллельно с помощью Http::pool и Http::batch. Приводятся практические примеры, обработка ответов и советы по таймаутам.