حالت تاریک
فصل ۱۳ — قراردادها
خلاصهٔ تحلیلی — این متن تحلیل فارسیِ مفاهیم فصل است، نه ترجمهٔ واژهبهواژه.
مسئله و زمینه
قرارداد در این فصل فقط API یا schema نیست: هر قالبی که اجزای معماری با آن اطلاعات یا وابستگی ردوبدل میکنند قرارداد است؛ از dependency کتابخانه و cache تا نقطهٔ یکپارچهسازی درونسازمانی و بیرونی. قرارداد نیرویی cross-cutting است که بر coupling ایستا و پویای کل معماری اثر میگذارد. انتخاب REST، gRPC یا JSON تصمیم پیادهسازی است؛ تصمیم معماریِ مقدم بر آن، مقدار سختگیری و نوع وابستگی موردنیاز میان همکاران است.
قرارداد سختگیرانه و شل
Strict contract نام، نوع، ترتیب، فیلدهای لازم و قواعد را دقیقاً تعیین میکند. RPC و gRPC نمونههای نزدیک به فراخوانی متد از راه دورند؛ schema معتبرشده نیز JSON را سختگیرانه میکند. این دقت، documentability خوب، اعتبارسنجی در build و اطمینان بالا از شکل داده را فراهم میکند. در مقابل، تغییر قرارداد به تغییر هماهنگ provider و consumer میانجامد و versionها، اگر راهبرد حذف تدریجی نداشته باشند، به بدهی عملیاتی تبدیل میشوند.
Loose contract معمولاً پیامهای name-value با metadata کم است. REST منبعمحور و GraphQLِ انتخابگر داده، در قیاس با RPC ظرفیت coupling سستتری دارند. افزودن اطلاعاتی که consumer استفاده نمیکند، لزوماً او را نمیشکند و هر bounded context میتواند مدل داخلی خود را مستقلتر تکامل دهد. بهای این آزادی، خطای نام فیلد، دادهٔ ناقص و انتقال بخشی از validation به برنامه و فرایند مهندسی است.
پس این انتخاب دوگانهٔ «خوب/بد» نیست. یک قرارداد سفت زمانی موجه است که semantic coupling واقعی، تغییر همزمان و نیاز جدی به تضمین وجود دارد. قرارداد شل زمانی ارزش دارد که نرخ تغییر یا استقلال انتشار طرفها مهم باشد—برای نمونه، اپ موبایلی که انتشار نسخهٔ آن زیر کنترل و زمانبندی متفاوت فروشگاه است.
Consumer-driven contracts: استقلال همراه با تضمین
consumer-driven contract تضاد ظاهریِ loose coupling و contract fidelity را حل میکند. بهجای آنکه provider تنها شکل داده را اعلام کند، هر consumer نیازهای قابلتست خود را تعریف میکند و provider آن آزمون را در pipeline نگه میدارد. بنابراین provider بدون حدسزدن تمام نیازهای آینده، همان نیاز واقعی را در build تأیید میکند.
این روش امکان سختگیری انتخابی را میدهد: consumer میتواند صرفاً وجود یک فیلد را بخواهد یا دامنهٔ ارزش آن را هم بررسی کند. در عوض به تیمهای منضبط، CI قابلاعتماد و مسئولیتپذیری دوطرفه نیاز دارد؛ loose payload و آزمون قرارداد، دو سازوکار مکملاند و نه یک راهحل جادویی.
Stamp coupling و مرز استفادهٔ آن
در stamp coupling یک ساختار بزرگ میان سرویسها میچرخد، درحالیکه هر گیرنده بخش کوچکی از آن را مصرف میکند. استفادهٔ «برای شاید بعداً لازم شود» از پروفایل کامل مشتری برای consumerی که فقط نام را میخواهد، anti-pattern است: تغییر بیربط قرارداد را میشکند و در بار بالا، هزینهٔ پهنایباند بهشدت رشد میکند.
بااینحال stamp coupling کاربرد مشروع هم دارد. در choreography پیچیده، پیام میتواند state گردشکار، نتیجهٔ گامها و خطا را حمل کند تا سرویس بعدی بدون پرسوجوی coordinator اطلاعات لازم را داشته باشد. این کار scale و throughput را بهبود میدهد، اما صریحاً قرارداد را به همکاران وابسته و payload را بزرگتر میکند. باید آن را هزینهای آگاهانه برای حمل semantic context دانست، نه راهی برای پنهانکردن آن.
راهنمای عملی و بدهبستانها
- قرارداد را بر پایهٔ «حداقل اطلاعات لازم برای consumer» طراحی کنید، نه مدل داخلی کامل provider.
- نرخ تغییر، محدودهٔ انتشار، نیاز امنیتی و میزان semantic coupling را قبل از انتخاب strictness بسنجید.
- برای قراردادهای شل، consumer-driven tests یا fitness functionهای قابلاجرا در CI بسازید؛ صرف مستندسازی کافی نیست.
- versioning را همراه با دورهٔ همزیستی و deprecation policy مشخص کنید؛ نگهداری بیپایان نسخهها انعطاف نیست.
- حجم و حساسیت payload را در محاسبات واقعی throughput و PII وارد کنید.
نکات کلیدی فصل
- قرارداد همهٔ مسیرهای انتقال اطلاعات و وابستگی را دربرمیگیرد، نه فقط endpoint.
- strict contract اطمینان و قابلیت بررسی میدهد، اما سرعت تکامل مستقل را کم میکند.
- loose contract قابلیت تکامل میدهد، اما به governance خودکار و بلوغ تیم وابسته است.
- consumer-driven contract پلی میان استقلال consumer و تضمین provider است.
- stamp coupling غالباً coupling تصادفی است، اما برای حمل state workflow میتواند انتخابی موجه باشد.
یادداشتهای مترجم
- contract، consumer-driven contract، fitness function و stamp coupling بهصورت لاتین حفظ شدهاند، زیرا نام الگوها و ابزارهای جستوجوپذیر معماریاند.
- «شل» در این متن به معنی قرارداد کمتجویزی و تکاملپذیر است، نه قرارداد بیقاعده یا بدون اعتبارسنجی.