نسخهگذاری API و سازگاری عقبرو: قراردادهایی که کلاینت را نمیشکنند
استراتژی URL/header versioning، تغییرات امن در schema، و سیاست deprecate برای APIهای عمومی و داخلی محصول.
علی مرتضوی
بنیانگذار پارادایس کد
سازگاری یک ویژگی محصول است نه جزئیات فنی
هر فیلد حذفشده یا معنای عوضشده، برای کسی که شما نمیبینید شکست است: اپ موبایل قدیمی، اسکریپت مشتری، یا یکپارچگی شریک. نسخهگذاری یعنی قول زمانی برای تغییر. بدون قول، سرعت فیچر با بیاعتمادی به API عوض میشود.
اول مشخص کنید API عمومی است یا داخلی. داخلی هم نسخه میخواهد، اما چرخه deprecate میتواند کوتاهتر باشد.
انتخاب مکان نسخه: مسیر، هدر، یا media type
نسخه در URL (`/v1/...`) شفاف و برای gateway/لاگ ساده است. هدر برای زیبایی URI وسوسهانگیز است اما کشف و کش را سختتر میکند. برای اکثر محصولات B2B و موبایل، نسخهٔ مسیر قابلفهمترین قرارداد است.
نسخهٔ عمده را برای شکست واقعی نگه دارید. تغییرات additive نباید v2 بسازند؛ وگرنه انفجار نسخه دارید نه انضباط.
تغییرات امن در برابر شکستن
امن معمولاً یعنی: فیلد اختیاری جدید، endpoint جدید، enum جدید که کلاینت ناشناس را نادیده میگیرد. شکستن یعنی: حذف فیلد، تغییر نوع، تغییر معنای پیشفرض، الزامی کردن فیلد قبلیِ اختیاری.
برای rename، دورهٔ دوبهدویی داشته باشید: فیلد قدیم و جدید همزمان، بعد هشدار deprecate، بعد حذف در نسخهٔ عمده.
قرارداد تستپذیر و Consumer-driven
قرارداد OpenAPI/Protobuf باید در CI validate شود. تست سازگاری جلوِ ادغام، جلوی «اپدیت بیصدا» را میگیرد. برای تیمهای چندکلاینتی، قرارداد مصرفکننده ارزشش را زود نشان میدهد.
نمونهٔ پاسخ واقعی را در مستند نگه دارید—نه فقط schema. کلاینتها از مثال کپی میکنند؛ مثال کهنه یعنی باگ توزیعشده.
سیاست deprecate با تاریخ و متریک
deprecate بدون تاریخ و بدون اندازهگیری ترافیک روی نسخهٔ قدیم، نمایشی است. تاریخ sunset اعلام کنید، مصرف را مانیتور کنید، و با صاحبان کلاینت ارتباط بگیرید.
برای موبایل، واقعیت store را بپذیرید: کاربران آپدیت نمیکنند. گاهی باید نسخهٔ قدیم را طولانیتر زنده نگه دارید یا قابلیت را سمت سرور feature-flag کنید.
نسخهٔ داخلی سرویسها و رویدادها
همان اصول برای پیامها و gRPC صدق میکند: فیلد را حذف نکنید، compatibility mode داشته باشید، و مصرفکنندهٔ ناشناس را تحمل کنید.
لایهٔ anti-corruption در مرزها کمک میکند مدل داخلی آزادانهتر عوض شود بدون اینکه قرارداد بیرونی بلرزد.
سؤالات متداول
هر تغییر UI نیاز به نسخه API جدید دارد؟
خیر. فقط تغییرات شکستن قرارداد. فیچر جدید معمولاً فیلد/endpoint اختیاری اضافه میکند.
چند نسخه را همزمان زنده نگه داریم؟
هرچه کمتر بهتر—معمولاً N و N-1. بیشتر از آن هزینهٔ تست و امنیت را منفجر میکند مگر تعهد قراردادی داشته باشید.
آیا GraphQL نسخهگذاری را حذف میکند؟
حذف نمیکند؛ شکلش عوض میشود. deprecate فیلد و تحمل کلاینتهای قدیمی همچنان لازم است.
دانش و مقالات
نیاز به اجرای همین مفاهیم در محصولتان دارید؟
پارادایس کد از مشاوره تا پیادهسازی کامل کنار شماست.