امنیت، هویت، استقرار و تابآوری · فصل ۷ — Dependency، Contract، Event و Network Failure · 114
Contract Drift
failure را بعد از وقوع و بهصورت موردی تحلیل میکند و هنوز detection، containment و repair path از قبل طراحی نشده است. موضوع جاری: «Contract Drift». میتواند failure family «Contract Drift» را بازتولید/تشخیص دهد و detection، containment و recovery مناسب را تعیین کند.
خلاصهٔ درس
failure را بعد از وقوع و بهصورت موردی تحلیل میکند و هنوز detection، containment و repair path از قبل طراحی نشده است. موضوع جاری: «Contract Drift».
میتواند failure family «Contract Drift» را بازتولید/تشخیص دهد و detection، containment و recovery مناسب را تعیین کند.
خروجی این درس
میتواند failure family «Contract Drift» را بازتولید/تشخیص دهد و detection، containment و recovery مناسب را تعیین کند.
1. مسئله اصلی: contract file، implementation و consumer سه چیز متفاوتاند
در Contract Drift ممکن است producer، consumer و فایل OpenAPI هر کدام از دید خود «درست» باشند ولی روی operation، required field، status code یا semantics توافق نداشته باشند. این درس سه لایه را جدا میکند: قرارداد اعلامشده، رفتار مشاهدهشده implementation و فرض/وابستگی consumer. بدون هر سه، اعلام breaking change ممکن است زودهنگام باشد.
2. OpenAPI توضیح interface است، نه گواه runtime
OpenAPI 3.2 یک interface description مستقل از زبان برای HTTP APIها تعریف میکند تا انسان و ابزار بتوانند قابلیتهای سرویس را بفهمند. نسخه منتشرشده فعلی 3.2.1 است. [OAS-321] اما وجود یک OpenAPI Description بهتنهایی ثابت نمیکند deployment دقیقاً همان رفتار را دارد؛ این تمایز برای تشخیص drift حیاتی است.
3. schema validation همه تخلفهای specification را نمیگیرد
صفحه رسمی schemaهای OpenAPI صریحاً میگوید schemaها میتوانند خطاهای زیادی را بگیرند اما تضمین نمیکنند همه specification violationها را تشخیص دهند؛ در تعارض، متن specification مرجع است. [OAS-SCHEMA] پس «validator سبز شد» با «contract و runtime کاملاً منطبقاند» یکی نیست.
4. Drift را در سطح element مشخص کن
بهجای برچسب کلی «API شکسته»، مشخص کن چه چیزی تغییر کرده: path/operation، request parameter، required property، response field، enum domain، status code یا semantic meaning. همین element بعداً تعیین میکند چه consumerهایی واقعاً تحت تأثیرند.
5. تغییر additive همیشه breaking نیست
افزودن یک optional response property میتواند برای consumerای که فیلد ناشناخته را نادیده میگیرد additive و non-breaking باشد. اما اگر consumer strict parser دارد، همان تغییر ممکن است اثر متفاوتی داشته باشد. بنابراین compatibility property فقط از diff فایل بهتنهایی به دست نمیآید.
6. optional → required معمولاً consumer dependency میخواهد
اگر propertyای که consumer قبلاً نمیفرستاد required شود، درخواستهای قبلی میتوانند رد شوند. برای اعلام breaking، هم diff قرارداد را ثبت کن و هم نشان بده consumer واقعاً به شکل قدیمی درخواست میفرستد یا به optional بودن وابسته است. بدون consumer evidence فقط «candidate breaking change» داری.
7. status code بخشی از قرارداد رفتاری است
تغییر status code ممکن است body schema را دستنخورده بگذارد ولی retry، fallback یا error mapping consumer را بشکند. مثال fixture: consumer فقط روی 429 retry میکند، ولی producer جدید همان condition را 400 برمیگرداند. این یک drift معنایی/رفتاری است، نه صرفاً schema mismatch.
8. enum narrowing میتواند breaking باشد
افزودن enum value و حذف enum value اثر یکسان ندارند. اگر consumer مقدار حذفشده را واقعاً میفرستد یا انتظار دارد، narrowing میتواند breaking باشد. ولی اگر مقدار حذفشده هیچوقت در consumer path استفاده نمیشود، impact باید از evidence استخراج شود نه از ترس worst-case.
9. docs stale با contract change یکی نیست
ممکن است فایل contract بین vA و vB تغییر نکرده باشد اما synthetic implementation response چیز دیگری نشان دهد. در این حالت مسئله «implementation vs declared contract divergence» است، نه لزوماً change بین دو contract version. repair ممکن است deployment rollback، implementation correction یا document update باشد؛ ابتدا باید authority واقعی مشخص شود.
10. compatibility class را از سه ورودی بساز
برای هر element این سه ستون را کنار هم بگذار: declared diff، observed behavior و consumer assumption/dependency. خروجی میتواند ADDITIVE_COMPATIBLE، BREAKING_FOR_OBSERVED_CONSUMER، IMPLEMENTATION_DIVERGENT یا UNKNOWN باشد. این درس policy جهانی برای همه APIها تعریف نمیکند؛ classification به fixture و consumer profile محدود است.
11. containment با repair فرق دارد
Containment میتواند route قدیمی را موقتاً نگه دارد، feature را freeze کند، compatibility shim فعال کند یا rollout را متوقف کند. Repair یعنی contract و implementation و consumer دوباره به یک وضعیت توافقشده برسند: backward-compatible producer، coordinated consumer migration، versioned endpoint یا اصلاح docs/runtime. containment را evidence پایان کار معرفی نکن.
12. counterexample: تغییر additive که consumer نادیده میگیرد
یک fixture property اختیاری جدید به response اضافه میکند و consumer profile صریحاً unknown fieldها را ignore میکند. اگر learner هر diff را breaking اعلام کند، این case او را رد میکند. diff وجود دارد، ولی observed consumer impact ندارد؛ بنابراین classification باید additive/non-breaking باقی بماند.
13. Transfer: از REST به webhook callback
در transfer، دیگر success response اصلی مرکز تصمیم نیست؛ قرارداد callback، payload و acknowledgement behavior مهم میشود. یک callback field که required شده و receiver قدیمی آن را ندارد میتواند breaking باشد. learner باید compatibility را از evidence webhook بازسازی کند و rules REST fixture را کورکورانه کپی نکند.
14. Lab: هشت fixture و ۶۴ assertion
Lab کاملاً local، deterministic و synthetic است. هشت case شامل baseline سالم، required-input break، additive ignored field، status semantic break، stale-doc/runtime divergence، enum narrowing، evidence ناقص و webhook transfer است. evaluator پنهان هشت dimension را برای هر case میسنجد؛ مجموعاً ۶۴ assertion.
15. Exit checklist و مرز ادعا
برای خروج باید بتوانی declared contract، observed behavior و consumer assumption را جدا ثبت کنی؛ diff element را دقیق نام ببری؛ additive و breaking را از consumer evidence بسازی؛ schema-validator سبز را proof runtime ندانی؛ docs stale را از version drift جدا کنی؛ containment و repair را تفکیک کنی؛ در evidence ناقص حالت OPEN را حفظ کنی؛ و webhook transfer را از صفر حل کنی. این fixture مصنوعی هیچ ادعایی درباره conformity یک API واقعی نمیکند.
ارزیابی
پاسخنامهی این درس در بستهی آموزش وجود ندارد؛ خودت جواب بده و صادقانه علامت بزن. «نیاز به مرور» درس را به صف تکرار میفرستد.
FLR-004-AF1 formative
FLR-004-AF2 formative
FLR-004-AF3 formative
FLR-004-AS1 summative
FLR-004-AS2 transfer
ملاکهای ارزیابی (rubric)
| Dimension | Sufficient evidence | Blocking failure |
|---|---|---|
| Evidence layers | Declared contract, observed behavior, and consumer assumption are separate | Contract file treated as runtime proof |
| Drift element | Exact operation/field/status/enum/semantic element identified | Generic “API broke” label only |
| Compatibility judgment | Additive/breaking classification tied to consumer evidence | Every diff automatically labeled breaking |
| Repair boundary | Containment separated from compatibility/coordinated repair | Temporary containment presented as closure |
| Verification/transfer | Independent rerun and webhook transfer rebuild the decision | Green validator or copied REST answer treated as proof |
منابع و تازگی
مطالعهٔ موارد (case studies)
تصاویر درس
فایلهای آزمایشگاه
Use only the supplied deterministic synthetic fixtures. For each case, build API Contract Drift Record v1.
Keep declared contract, observed behavior, and consumer assumption separate. Do not treat a schema-valid OpenAPI file as proof that the synthetic implementation conforms. Do not call every diff breaking: consumer impact is required. Preserve UNKNOWN when evidence is incomplete.
The transfer case changes the interaction model from REST request/response to webhook callback. Rebuild the compatibility decision from callback evidence rather than copying the REST rules.
رسانه و اسلایدهای درس
فایلهای آموزشی (دانلود)