Laravel Idempotency: جلوگیری از اجرای تکراری درخواستها
خلاصهٔ کاملتر
یه مشکل کلاسیک توی APIهای وب اینه که کلاینتها ممکنه بهخاطر قطعی شبکه یا timeout، یه درخواست رو چند بار بفرستن. اگه اون درخواست یه پرداخت یا ثبت سفارش باشه، اجرای مجدد لاجیک میتونه فاجعهبار باشه. پکیج Laravel Idempotency دقیقاً برای حل این مشکل اومده.
این پکیج که توسط Wendell Adriel منتشر شده، یه میدلور HTTP به لاراول اضافه میکنه. کار اصلیش اینه که وقتی یه درخواست با یه Idempotency-Key مشخص میرسه، جواب اون رو کش میکنه. اگه همون درخواست دوباره با همون کلید و همون دادهها اومد، دیگه کنترلر اجرا نمیشه و همون جواب قبلی با یه هدر اضافهی Idempotency-Replayed: true برمیگرده.
دو روش برای فعال کردن این قابلیت روی روتها وجود داره. روش اول استفاده از میدلور استاندارد لاراوله که میشه مستقیم به روت وصلش کرد. روش دوم استفاده از PHP Attribute هست که روی کلاس یا متد کنترلر قرار میگیره. هر دو روش گزینههای یکسانی دارن و میشه باهاشون تنظیمات سفارشی داشت.
تنظیمات قابل شخصیسازی شامل TTL یا مدت نگهداری کش، زمان lockTimeout، اینکه کلید اجباری باشه یا نه، و اسم هدر موردنظر میشه. یکی از جالبترین قابلیتها، اسکوپبندی کلیده که میشه تعیین کرد کلید فقط برای یه یوزر خاص معتبر باشه، یا برای یه IP خاص، یا بهصورت سراسری برای همه.
پکیج دو سناریوی تعارض رو هم مدیریت میکنه. اگه یه درخواست با همون کلید بیاد ولی دادههاش فرق داشته باشه، خطای 422 برمیگرده. اگه هم یه درخواست مشابه در حالی بیاد که درخواست اول هنوز داره پردازش میشه، خطای 409 با هدر Retry-After: 1 برمیگرده تا کلاینت بفهمه کمی صبر کنه.
این مکانیزم تعارض از قفل اتمیک لاراول استفاده میکنه، به همین دلیل باید از یه درایور کش با قابلیت lock مثل Redis یا Memcached استفاده کرد. این یه پیشنیاز مهمه که قبل از راهاندازی باید بهش توجه کرد.
پکیج دو دستور Artisan هم داره که مدیریت کشهای idempotency رو راحتتر میکنه. با idempotency:list میشه لیست تمام کلیدهای فعال رو با جزئیاتشون دید. با idempotency:forget هم میشه کلیدهای خاص یا تمام کلیدهای یه یوزر یا IP رو پاک کرد. برای عملیاتهای مخرب هم قبل از اجرا تأیید میخواد، مگه که --force پاس بدی.
در کل این پکیج برای هر API که کلاینتهاش ممکنه درخواستها رو retry کنن یه ابزار خیلی کاربردیه. بهخصوص برای سیستمهای پرداخت، ثبت سفارش، و هر جایی که اجرای دوباره یه اکشن میتونه عواقب ناخواسته داشته باشه.
نکات کلیدی:
- درخواستهای تکراری با همون کلید و داده رو از کش جواب میده، بدون اجرای مجدد لاجیک
- دو روش پیادهسازی: میدلور روت و PHP Attribute
- سه نوع اسکوپ: بر اساس یوزر، IP، یا سراسری
- تشخیص تعارض: داده متفاوت → 422، درخواست همزمان → 409
- نیاز به درایور کش با پشتیبانی از قفل اتمیک (Redis یا Memcached)
- دستورات Artisan برای مشاهده و پاکسازی کشهای idempotency




