سازگاری قرارداد API
چرا سازگاری قرارداد
سازگاری قرارداد توانایی یک API برای تکامل بدون شکستن ادغام های موجود است. در سیستم های در حال رشد، API ها بیشتر از کد مشتری تغییر می کنند. سازگاری اجازه می دهد تا شما را به انتشار ویژگی های تکراری، بدون تنظیم «حرکت بزرگ».
ایده کلیدی: قرارداد اولیه است، تغییرات با توجه به قوانین سازگاری انجام می شود و به طور خودکار بررسی می شود.
مفاهیم پایه
قرارداد - مشخصات رابط رسمی: منابع/روش ها/رویدادها، طرح داده ها، کدهای خطا، محدودیت ها، SLA ها، الزامات امنیتی.
ارائه دهنده - صاحب API. مصرف کننده - مشتری/ادغام.
- عقب: تامین کننده جدید با مصرف کنندگان قدیمی کار می کند.
- به جلو: تامین کننده قدیمی با مصرف کنندگان جدید کار می کند (معمولا توسط «خوانندگان تحمل» به دست می آید).
- کامل: هر دو عقب و جلو (قوی ترین گزینه) مشاهده می شود.
- Additivity - اضافه کردن عناصر اختیاری بدون شکستن موجود.
خط مشی نسخه
نسخه بندی معنایی (توصیه می شود):- MAJOR - تغییرات شکستن (تنها زمانی که یک خط API جدید منتشر می شود: "/v2 "،" سرویس. v2 ').
- MINOR - تغییرات افزودنی (زمینه ها/روش های اختیاری جدید).
- PATCH - رفع بدون تغییر قرارداد.
- سیاست رد: اعلام عناصر منسوخ، پنجره پشتیبانی (غروب آفتاب)، هشدارها در هدر/ابرداده، برنامه برداشت.
امن در مقابل تغییرات خطرناک
امن (معمولا سازگار با عقب)
یک فیلد اختیاری به JSON/Protobuf/Avro اضافه کنید.
یک نقطه پایانی/روش/رویداد جدید اضافه کنید.
گسترش enum با ارزش های جدید اگر مصرف کنندگان تحمل ارزش های ناشناخته است.
افزایش حد (به عنوان مثال، «maxItems») بدون سفت کردن حداقل.
اضافه کردن nullable با پیش فرض درست است.
ویرایش متن توصیف/مثال.
خطرناک (سازگاری با شکست)
تغییر نام/حذف فیلدها، تغییر نوع یا اجباری آنها.
تغییر معنای کد وضعیت/خطا (به عنوان مثال، «200» بود، به «204» یا «404» تبدیل شد).
تغییر فرمت شناسه ها (UUID → int).
سفت از اعتبار (minimums سخت تر/الگوهای) بدون نسخه.
تغییر نظم و ساختار در جریان/رویدادهای gRPC.
استفاده مجدد از شماره برچسب در Protobuf برای زمینه های جدید.
قابلیت همکاری با سبک تعامل
طرح REST/HTTP + JSON
Additivity: ما زمینه های جدید را به عنوان «اختیاری »/« nullable» علامت گذاری می کنیم.
خواننده تحمل در مشتری: نادیده گرفتن زمینه های ناشناخته ؛ عدم اعتماد به نظم
نسخه بندی: عمده - در راه ('/v2 ') و یا در نوع رسانه (' برنامه/vnd. به عنوان مثال. v2 + json ').
ETag/If-Match: برای به روز رسانی امن بدون مسابقه.
خطاها: قالب واحد («نوع»، «کد»، «عنوان»، «جزئیات»، «ردیابی _ id»)، مقدار «کد» را بدون یک major تغییر نمی دهد.
صفحه بندی: نشانگر ها به افست ترجیح داده می شوند. فیلدهای «next _ cursor» را اضافه کنید، معنی فیلدهای موجود را تغییر ندهید.
gRPC/Protobuf
شماره گذاری بدون تغییر است. برچسبهای حذف شده قابل استفاده مجدد نیستند.
فیلدهای جدید «اختیاری »/« تکراری» با پیش فرض های معقول در سرور هستند.
هنوز سفارش و پیام های اجباری در جریان-RPC را تغییر دهید.
وضعیت خطا پایدار است («INVALID _ ARGUMENT»، «FAILED _ PRECONDITION»، و غیره) ؛ معناشناسی جدید → نسخه جدیدی از روش/سرویس.
رویداد محور (Kafka/NATS/Pulsar) + طرح آورو/JSON
نامگذاری رویدادها: "دامنه. فعالیت. v {سرگرد}.
زمینه های جدید اختیاری هستند ؛ جداسازی هسته و غنی سازی («غنی شده»).
ثبات های طرح: قوانین سازگاری (BACKWARD/FORWARD/FULL) در موضوع/رویداد.
پسوند enum برای خواننده تحمل مصرف کننده معتبر است.
تغییر کلید پارتیشن/سفارش برای aggregate = تغییرات شکستن.
GraphQL
اضافه کردن فیلدها/انواع امن است ؛ حذف/تغییر نام - فقط از طریق @ deprecated و پنجره مهاجرت.
نوع/non-nullable را بدون major تغییر ندهید.
کنترل پیچیدگی/عمق - محدودیت ها بخشی از قرارداد هستند.
الگوهای تکامل پایدار
افزودنی اول: گسترش بدون شکستن.
مذاکره قابلیت: مشتریان گزارش می دهند که آنها پشتیبانی می کنند (هدر/پارامترها/موافقت نامه ها)، سرور تنظیم می کند.
مرزهای قرارداد: رفع MGC (حداقل قرارداد گارانتی) و پسوند جداگانه (مدل هرم معکوس).
Tolerance به طور پیش فرض: مشتریان غیر ضروری را نادیده می گیرند و به درستی مقادیر ناشناخته (fallback) را مدیریت می کنند.
Dual-write/Dual-emit: برای تغییرات عمده، «v1» و «v2» را به صورت موازی برای مدتی آزاد کنید.
Headers/Events Sunset: وقتی نسخه ها حذف می شوند، از قبل اطلاع دهید.
مدیریت و اتوماسیون
خطوط API:- OpenAPI/طیفی: نامگذاری، صفحه بندی، کدهای خطا، فرمت های زمینه.
- Buf/Protobuf: عدم استفاده مجدد از برچسب ها، نماد بسته.
- AsyncAPI/Schema Registry: سازگاری طرح در سطح CI.
- کاتالوگ قرارداد (SSOT): ثبت نام طرح/نسخه متمرکز با تاریخچه پراکنده.
- API Guild: انجمن/کمیته ای که قوانین، قالب ها و تغییرات را تصویب می کند.
- مدیریت تغییر: RFC/ADR، یادداشتهای انتشار، راهنماهای مهاجرت.
تست سازگاری
Schema-diff در CI: کیک های شکستن بلوک (OpenAPI-diff، شکستن Buf، سازگاری SR).
قراردادهای مبتنی بر مصرف کننده (CDC): پیمان/مشابه - تامین کننده در مقابل قراردادهای خاص مصرف کننده.
نمونه های طلایی: نمایش داده شد مرجع/پاسخ و حوادث برای رگرسیون.
E2E Canary: رول کردن به سهم ترافیک/گروه های مصرف کننده فردی.
Chaos/latency: Timeout/Retray check - تغییر SLO به عنوان تغییر قرارداد در نظر گرفته می شود.
مهاجرت و استهلاک
1. Declare deprecate: علامت گذاری مورد، مشخص کردن اصطلاح غروب خورشید و جایگزین.
2. دوره سازگاری را حفظ کنید: dual-write/dual-emit، پل ها، آداپتورها.
3. جمع آوری تله متری: چه کس دیگری از قدیمی استفاده می کند ؟
4. ارتباطات: نامه های پستی، یادداشت های انتشار، تست می ایستد.
5. حذف: پس از پایان پنجره - حذف با انتشار ثابت.
مثال هایی از تغییرات
استراحت
این بود:json
{ "id":"p1", "status":"authorized" }
تبدیل شد (افزودنی، ایمن):
json
{ "id":"p1", "status":"authorized", "risk_score": 0. 12 }
مشتریانی که زمینه های ناشناخته را نادیده می گیرند، شکسته نمی شوند.
پروتبوف
proto message Payment {
string id = 1;
string status = 2; // don't change tag numbers optional double risk_score = 3; // additive
}
رویداد
حق الزحمه. مجاز است. v1 '(هسته) +' پرداخت. غنی شده v1 '(غنی سازی). مصرف کنندگان مسیر بحرانی هسته را می خوانند و وابسته به غنی سازی نیستند.
ضد ضربه
Swagger-wash: مشخصات رسمی وجود دارد، اما رفتار سرویس با آن مخالف است.
شکستن توسط خفا: تغییر نوع/وضعیت/فرمت بدون نسخه جدید و پنجره مهاجرت.
رویدادهای خام CDC به عنوان یک قرارداد عمومی: طرح DB نشت، عدم امکان تکامل.
مشتری سخت: قطره در زمینه های ناشناخته/ارزش ؛ عدم وجود یک خواننده تحمل.
استفاده مجدد از برچسب های protobuf: فساد اطلاعات آرام.
تاخیر به عنوان «غیر قرارداد»: p95 به طور غیر منتظره طولانی شد - مصرف کنندگان در زمان وقفه شکسته می شوند.
چک لیست سازگاری (قبل از ادغام)
- تغییرات افزودنی هستند (یا نسخه اصلی آماده شده).
- Linters/diff checks گذشت، قوانین سازگاری سبز هستند.
- خطاها/کدها/وضعیتها معناشناسی را تغییر ندادند.
- Enum بدون ممنوعیت ارزش های قدیمی گسترش یافته است ؛ مشتریان - تحمل.
- مرزهای MGC بدون تغییر هستند.
- نمونه های به روز شده/مستندات/SDK.
- برای عمده - طرح دو نوشتن/دو انتشار، غروب آفتاب تاریخ، کام طرح.
[آزمایش CDC/Golden/E2E گذشت.
سوالات متداول
چه تفاوتی با سازگاری رو به جلو دارد ؟
Backward - سرورهای جدید مشتریان قدیمی را خراب نمی کنند. رو به جلو - مشتریان جدید بر روی سرورهای قدیمی شکستن نیست (از طریق خواننده تحمل و پیش فرض شسته و رفته).
چه زمانی «/v2 »را انجام می دهید ؟
هنگامی که متغیرها/معانی تغییر می کنند، فیلدها/روش ها حذف می شوند، یک مدل امنیتی جدید مورد نیاز است - شروع یک خط جدید آسان تر و صادقانه تر است.
آیا می توانید بدون Schema Registry/linters زندگی کنید ؟
از لحاظ نظری - بله، عملا - اینها رگرسیون های مکرر و خرابی های «پنهان» هستند. اتوماسیون پرداخت می کند.
Enum می تواند تمدید شود ؟
بله، اگر مشتریان به درستی مقادیر ناشناخته را مدیریت کنند (عقب نشینی/نادیده گرفتن). در غیر این صورت، سرگرد.
مجموع
سازگاری قرارداد قوانین + نظم + اتوماسیون است. طراحی additively، تغییرات شکستن نسخه، اعمال یک خواننده تحمل، به طور خودکار diffs و CDC بررسی، طرح مستهلک. به این ترتیب API ها می توانند به سرعت تکامل یابند و یکپارچگی می تواند پایدار باقی بماند.