چرا Tempest برای ساختِ API دلنشینه
خلاصهٔ کاملتر
نویسنده (Steve McDougall) با توصیفِ یه نسخه از توسعهی API شروع میکنه که توش هر تصمیم، تصمیمِ بعدی رو سنگینتر میکنه: یه لایهی validation میخوای، پس یه request class لازمه؛ اون آرایهی خام برمیگردونه، پس یه DTO میخوای؛ DTO باید از request ساخته بشه، پس یه factory method میخوای. تا وقتی یه شیءِ typeدار دستت بیاد، چهارتا فایل رو باز کردی و یه اسمِ فیلد رو سه بار نوشتی. هیچکدوم دقیقاً غلط نیست، ولی کلی «حرکتِ اضافه» برای یه کارِ سادهست.
به گفتهی نویسنده، Tempest موضع دیگهای میگیره: فریمورک دورِ این ایده ساخته شده که باید کمترین کدِ مرتبط با فریمورک رو بنویسی، و هیچجا این بیشتر از نحوهی مدیریتِ دادهی ورودی مشخص نیست. تو Tempest، یه request class یه کلاسِ سادهی PHPه که اینترفیسِ Request رو implement میکنه و از trait به اسم IsRequest استفاده میکنه. فیلدهای موردانتظار رو بهصورت propertyهای public و typeدار اعلام میکنی و قوانینِ validation هم مستقیم روی همون propertyها بهشکلِ اتریبیوتِ PHP 8 میشینن. همین؛ چیزِ دیگهای برای پیکربندی نیست.
وقتی این کلاس به اکشنِ کنترلر تزریق میشه، Tempest دادهی ورودی رو از قبل validate و یه شیءِ کاملاً typeدار رو hydrate کرده. مثلاً $request->first_name تضمیناً یه stringه، نه mixed و نه array. نکتهی مهم اینه که خودِ این request همون DTOه؛ قدمِ جدایی برای نگاشتِ دادهی validateشده به یه شیءِ typeدار وجود نداره، چون شیء همونجا کاملاً پر شده و آمادهست.
بخشِ دیگهای که به گفتهی نویسنده حسِ توسعهی API رو فرق میده، routingِ مبتنی بر discoveryه. مسیرها تو یه فایلِ جدا اعلام نمیشن، بلکه بهشکلِ اتریبیوت روی متدهای کنترلر، درست کنارِ کدی که هندلشون میکنه، زندگی میکنن. Tempest موقعِ boot این اتریبیوتها رو کشف و مسیرها رو خودکار ثبت میکنه، پس نه فایلِ routeی برای نگهداری هست و نه احتمالِ اینکه تعریفِ مسیر از کنترلرش جدا بیفته.
نویسنده میگه واژهی «declarative» زیاد استفادهی بیجا میشه، ولی اینجا درست بهکار میره: هر اطلاعاتی دربارهی یه request — چه فیلدهایی داره، چه تایپی، چه قوانینی — روی خودِ کلاس اعلام شده. کلاس رو میخونی و همهچی رو میدونی، بدون اینکه بین یه متدِ rules()، سازندهی DTO و یه مرحلهی نگاشت رفتوبرگشت کنی. اتریبیوتهای PHP 8 همیشه برای اینجور کار مناسب بودن و Tempest یکی از اولین فریمورکهاییه که بهجای یه wrapperِ راحتی، اونها رو بهعنوان یه تصمیمِ طراحیِ اصلی میبینه.
نکات کلیدی:
- Tempest دورِ این ایده ساخته شده که کمترین کدِ فریمورکی رو بنویسی.
- request class یه کلاسِ ساده با propertyهای typeدارِ publicه؛ قوانینِ validation بهشکلِ اتریبیوت روی همون propertyها میشینن.
- خودِ request همون DTOه؛ قدمِ جدا برای نگاشتِ دادهی validateشده لازم نیست.
- مسیرها بهجای فایلِ جدا، بهشکلِ اتریبیوت کنارِ متدِ کنترلر تعریف میشن و موقعِ boot کشف میشن.
- تایپها نقشِ قرارداد و مستندسازی رو بازی میکنن؛ همهچیز روی خودِ کلاس اعلام شده.




