أفضل ممارسات إصدار RESTful API: لماذا v1 هو رقم #1
كريس مكفادن
24/05/2017
البريد الإلكتروني
1 min read

النقاط الرئيسية
يعوق إصدار واجهة برمجة التطبيقات التغييرات المدمرة ويحافظ على الثقة بين مزودي واجهة برمجة التطبيقات والمطورين.
تساعد اتفاقيات إصدار واجهة برمجة التطبيقات الواضحة في تجنب مزيج فوضوي من الإصدارات عبر النقاط الطرفية.
تجعل واجهات برمجة التطبيقات RESTful المقترنة مع URIs إصدار محددة وبسيطة التكاملات بديهية للمطورين.
تضمن مجموعات الحوكمة الاتساق عبر الفرق، مما يمنع التغييرات المدمرة العرضية.
ليس كل التغييرات تتطلب إصدارًا جديدًا — فقط تلك التي تكسر التكاملات القائمة.
يعتبر التوثيق الجيد ضروريًا لتجنب الارتباك ومنع التغييرات المدمرة غير المقصودة.
فصل النشر عن الإطلاق يسمح للفرق باختبار وتحسين النقاط الطرفية بأمان قبل الإعلان عنها.
عندما تكون التغييرات المدمرة حتمية، يجب تقييمها وإبلاغها بعناية.
أبرز الأسئلة والأجوبة
لماذا يعتبر تحديد إصدارات API مهمًا؟
إنه يمنع التغييرات غير المتوقعة للمطورين الذين يدمجون مع API الخاص بك، ويحمي الثقة، ويضمن الاستقرار طويل الأمد للتطبيقات التي تعتمد على سلوك متسق.
ما هي التغييرات الجذرية في واجهة برمجة التطبيقات؟
أي تعديل يغير كيفية تصرف التكاملات الحالية — مثل إزالة النقاط النهائية، تغيير الافتراضات، إضافة حقول مطلوبة، أو تعديل تنسيقات الاستجابة.
لماذا اختارت SparkPost استخدام REST كأساس لواجهة برمجة تطبيقاتها؟
استخدام REST لـ HTTP و JSON يسهل على المطورين عبر اللغات (PHP، روبي، جافا، إلخ) الدمج دون الحاجة إلى معرفة متخصصة بالأنظمة الأساسية.
كيف قررت SparkPost على منهجها في الترقيم؟
لقد قاموا بتقييم إصدار Accept-header مقابل إصدار URI واختاروا إصدار URI لأنه صريح وبسيط وأكثر سهولة للمطورين.
ما هو الدور الذي تلعبه مجموعة إدارة API؟
يُنشئ معايير، يفرض التناسق، ويمنع الفرق من إدخال تغييرات تتعارض مع الاتفاقيات أو تكسر التوافق.
ما هي أنواع التغييرات التي لا تعتبر كبيرة؟
إضافة معلمات اختيارية جديدة، تقديم نُقاط نهاية جديدة، إضافة مفاتيح جديدة في حمولات JSON، أو تغيير نُقاط النهاية غير العامة — أي شيء لا يعطل السلوك الحالي.
ما هي التغييرات التي تعتبر معطلة؟
إضافة المعلمات المطلوبة، إزالة النقاط النهائية، تغيير السلوكيات الافتراضية، تعديل هيكل الاستجابة، أو إدخال حقول JSON المطلوبة.
لماذا تعتبر الوثائق الدقيقة ضرورية؟
إنه يمنع التغييرات غير المقصودة، ويساعد المطورين على فهم السلوك، ويضمن أن تقوم الفرق بتحديث API بشكل موثوق. استخدمت SparkPost لغة Markdown (API Blueprint) وGitHub للحفاظ على الوضوح والانفتاح.
ما هي الفائدة من فصل نشر البرمجيات عن إصدارها؟
يمكن للفرق نشر نقاط نهاية جديدة أو تحسينات بشكل مستمر داخليًا، اختبارها في سير العمل الفعلي، تنقيح السلوكيات، وإصدارها علنًا فقط بمجرد استقرارها — لتجنب الكشف المبكر والذي قد يكون ضارًا.
ماذا يحدث إذا أصبحت هناك ضرورة لتغيير جذري؟
يجب أن يكون ذلك نادرًا، ومبررًا بفوائد واضحة، ويتم تقييمه بعناية من حيث تأثيره على المستخدم، ويجب التواصل بشأنه بشكل شامل. مثال: تعديل Suppression API فقط بعد تأكيد الحد الأدنى من التأثير وتقديم إشعار.
إذاً، إلى أي مدى يمكن أن يكون إصدار واجهة برمجة التطبيقات API صعبًا؟ الحقيقة أنه ليس كذلك، ولكن ما هو صعب هو الحفاظ على بعض العقلانية بتجنب التفريع غير الضروري إلى عدد مذهل من الإصدارات والنسخ المطبقة عبر عشرات من نقاط نهاية واجهة برمجة التطبيقات مع توافق غير واضح.
التغييرات الجذرية سيئة! استخدام إصدار API جيد!
كما يدرك أي شخص قام ببناء API أو يستخدمه بانتظام عاجلاً أم آجلاً، فإن التغييرات الجذرية سيئة للغاية ويمكن أن تكون لطخة خطيرة على API مفيد في غير ذلك. التغيير الجذري هو تغيير في سلوك API يمكن أن يكسر تكامل المستخدم ويؤدي إلى الكثير من الإحباط وفقدان الثقة بين مزود API والمستخدم. تتطلب التغييرات الجذرية أن يتم إبلاغ المستخدمين مسبقًا (مع اعتذارات مصاحبة) بدلاً من التغيير الذي يظهر فجأة، مثل ميزة جديدة ومبهجة. الطريقة لتجنب هذا الإحباط هي نسخ API مع تأكيدات من مالك API بأنه لن يتم إدخال تغييرات مفاجئة ضمن أي نسخة واحدة.
إذاً، كم يمكن أن يكون من الصعب نسخة API؟ الحقيقة أنها ليست صعبة، لكن ما هو صعب هو الحفاظ على بعض الاتزان بعدم التدهور بدون مبرر إلى عدد مثير للحيرة من النسخ والفرعيات المطبقة عبر العشرات من وظائف API مع توافقات غير واضحة.
لقد قدمنا النسخة v1 من API منذ ثلاث سنوات ولم ندرك أنها ستستمر بقوة إلى يومنا هذا. فكيف واصلنا توفير أفضل API لبدء تشغيل البريد الإلكتروني لأكثر من عامين وما زلنا نحافظ على نفس نسخة API؟ هذه الاستقرار ضرورية للمطورين الذين يبنون التطبيقات باستخدام email APIs in cloud infrastructure، حيث البساطة والموثوقية هما الأولوية الأقصى. بينما هناك العديد من الآراء المختلفة حول كيفية نسخ APIs REST، آمل أن تكون قصة نسختنا v1 الهادئة والقوية قد ترشدك في طريقك للحصول على بصيرة نسخة APIs.
الراحة هي الأفضل
حوكمة API
مع اختيار اتفاقية ترقيم النسخ، كان لدينا المزيد من الأسئلة. متى نقوم بزيادة النسخة؟ ما هو التغيير الجذري؟ هل سنقوم بتحديث النسخة لكل API أو فقط لنقاط نهاية معينة؟ في SparkPost، لدينا فرق متعددة تعمل على أجزاء مختلفة من API. داخل هذه الفرق، يعمل الأفراد على نقاط نهاية مختلفة في أوقات مختلفة. لذا، من المهم جدًا أن يكون API لدينا متسقًا في استخدام الاتفاقيات. كان هذا أعمق من مجرد ترقيم النسخ.
قمنا بإنشاء مجموعة حوكمة تشمل مهندسين يمثلون كل فريق، وعضوًا من فريق إدارة المنتج، والرئيس التنفيذي للتكنولوجيا لدينا. هذه المجموعة مسؤولة عن إنشاء وتوثيق وفرض سياسات API عبر جميع الفرق. كما أن قناة حوكمة API في Slack مفيدة للنقاشات الحية حول هذا الموضوع.
حددت مجموعة الحوكمة عددًا من الطرق التي يمكن بها إدخال التغييرات على API التي تكون مفيدة للمستخدم ولا تشكل تغييرًا جوهريًا. وتشمل هذه:
مصدر جديد أو نقطة نهاية API جديدة
معلمة اختيارية جديدة
تغيير إلى نقطة نهاية API غير عامة
مفتاح اختياري جديد في جسم JSON POST
مفتاح جديد يتم إرجاعه في جسم استجابة JSON
على النقيض من ذلك، يتضمن التغيير الجذري أي شيء يمكن أن يكسر تكامل المستخدم مثل:
معلمة جديدة مطلوبة
مفتاح جديد مطلوب في الأجسام الكتابية
إزالة نقطة نهاية موجودة
إزالة طريقة طلب نقطة نهاية موجودة
سلوك داخلي مختلف بشكل كبير لاستدعاء API – مثل تغيير في السلوك الافتراضي.
النسخة الكبيرة 1.0
عندما قمنا بتوثيق ومناقشة هذه الاتفاقيات، توصلنا أيضًا إلى استنتاج أنه من مصلحة الجميع (بما في ذلك نحن!) تجنب إجراء تغييرات جذرية على API لأن إدارة إصدارات متعددة تضيف قدرًا لا بأس به من العبء. قررنا أن هناك بعض الأشياء التي يجب أن نقوم بإصلاحها في API الخاص بنا قبل الالتزام بـ “v1”.
إرسال بريد إلكتروني بسيط كان يتطلب جهدًا كبيرًا جدًا. للحفاظ على 'الأشياء البسيطة بسيطة' قمنا بتحديث جسم POST لضمان تلبية كل من الحالات البسيطة والمعقدة. كان الشكل الجديد أكثر توافقًا مع المتطلبات المستقبلية أيضًا. ثانياً، قمنا بمعالجة مشكلة في نقطة النهاية الخاصة بالـ Metrics. كانت هذه النقطة النهائية تستخدم معلمة “group_by” التي كانت تقوم بتغيير شكل جسم استجابة GET بحيث يكون المفتاح الأول هو قيمة معلمة group by. لم يكن ذلك يبدو RESTful جدًا، لذلك قمنا بتفكيك كل مجموعة إلى نقطة نهاية منفصلة. وأخيراً، قمنا بتدقيق كل نقطة نهاية وقمنا بإجراء تغييرات طفيفة هنا وهناك لضمان توافقها مع المعايير.
توثيق دقيق
من المهم أن يكون لديك توثيق API دقيق وقابل للاستخدام لتجنب التغييرات التي قد تكون مقصودة أو غير مقصودة. قررنا استخدام نهج بسيط لتوثيق API باستخدام لغة Markdown تسمى API Blueprint وإدارة مستنداتنا في Github. يساهم مجتمعنا في تحسين هذه المستندات مفتوحة المصدر. كما نقوم أيضًا بالحفاظ على مجموعة غير علنية من المستندات في Github خاصة بواجهات وبرامج التوصيل الداخلية.
في البداية، نشرنا مستنداتنا على Apiary، وهي أداة رائعة للنماذج الأولية ونشر مستندات API. ومع ذلك، لم يكن إضافة Apiary إلى موقعنا الإلكتروني يعمل على الأجهزة المحمولة، لذا أصبحنا الآن نستخدم Jekyll لإنشاء مستندات ثابتة بدلاً من ذلك. مستندات SparkPost API الأحدث لدينا الآن تُحمّل بسرعة وتعمل بشكل جيد على الأجهزة المحمولة، وهو الأمر المهم للمطورين الذين ليسوا دائمًا جالسين أمام جهاز الكمبيوتر الخاص بهم.
فصل النشر عن الإصدار
تعلمنا في وقت مبكر حيلة قيمة لفصل عملية النشر عن الإصدار. بهذه الطريقة، من الممكن نشر التغييرات بشكل متكرر عند جاهزيتها من خلال التسليم والنشر المستمرين، ولكننا لا نعلن عنها أو نوثقها بشكل علني دائمًا في نفس الوقت. ليس من غير المألوف أن نقوم بنشر نقطة نهاية API جديدة أو تحسين لنقطة نهاية API موجودة واستخدامها من داخل الواجهة أو مع الأدوات الداخلية قبل أن نقوم بتوثيقها ودعمها علنًا. بهذه الطريقة، يمكننا إجراء بعض التعديلات عليها لتحسين الاستخدام أو الامتثال للمعايير دون القلق بشأن إجراء تغيير مدمّر. بمجرد أن نكون راضين عن التغيير، نضيفه إلى توثيقنا العام.
أوه!
من الإنصاف الاعتراف بأنه كان هناك أوقات لم نرتق فيها إلى مثُلنا العليا "لا تغييرات جذرية" وهذه الأوقات تستحق التعلم منها. في إحدى المناسبات، قررنا أنه سيكون من الأفضل للمستخدمين إذا كان الإعداد الافتراضي لخاصية معينة هو true بدلاً من false. بعد أن نشرنا التغيير، تلقينا عدة شكاوى من المستخدمين لأن السلوك قد تغير بشكل غير متوقع. قمنا بإعادة الوضع إلى ما كان عليه وأضفنا إعدادًا على مستوى الحساب – وهو نهج أكثر ودية للمستخدمين بالتأكيد.
أحيانًا نشعر بالإغراء لإدخال تغييرات جذرية كنتيجة لإصلاح الأخطاء. مع ذلك، قررنا ترك هذه الخصوصيات كما هي بدلاً من المجازفة بإلحاق الأذى بتكاملات العملاء من أجل التناسق.
هناك حالات نادرة حيث اتخذنا القرار الجاد بإجراء تغيير جذري – مثل إيقاف مصدر أو طريقة API – لمصلحة المجتمع الأكبر من المستخدمين وفقط بعد التأكد من أن التأثير على المستخدمين ضئيل أو معدوم. على سبيل المثال، اتخذنا القرار عمدًا لتغيير سلوك الاستجابة لواجهة Suppression API ولكن فقط بعد الموازنة بعناية بين الفوائد والتأثيرات على المجتمع والتواصل بعناية حول التغيير مع مستخدمينا. ومع ذلك، لن نقدم أبدًا على إجراء تغيير قد يكون له تأثير مباشر على إرسال البريد الإلكتروني الإنتاجي لأحد المستخدمين.



