تصميم واجهة API عامة: العقد الذي لا تستطيع التراجع عنه

الإصدارات، والحدود، والمصادقة، والأخطاء — القرارات التي تصبح دائمة في اللحظة التي يبني عليها أول عميل.

الفرق بين واجهة داخلية وواجهة عامة ليس في الكود بل في القدرة على التغيير. الداخلية تعدّلها ظهيرة الثلاثاء؛ العامة تصبح عقداً في اللحظة التي يبني عليها أول عميل شيئاً يعتمد عليه.

احسم الإصدارات قبل النشر لا بعده

أضف الإصدار من اليوم الأول حتى لو كان `v1` وحده. إضافته لاحقاً يعني كسر كل عميل موجود. وعرّف صراحةً ما تعتبره تغييراً كاسراً: إضافة حقل ليست كسراً، لكن حذف حقل أو تغيير نوعه أو تضييق ما تقبله كلها كسر — وعملاؤك سيفترضون تعريفاً أضيق من تعريفك.

الترقيم بالمؤشّر لا بالإزاحة

الترقيم بـ `offset` يبدو أبسط ويفشل صامتاً: إن أُضيف صف بين طلبين، تكرّر عنصر أو اختفى. استخدم مؤشّراً (cursor) مبنياً على قيمة ثابتة ومرتّبة. الفرق لا يظهر في الاختبار وحده — يظهر بعد شهور في بيانات عميل ناقصة دون تفسير.

الأخطاء جزء من الواجهة

  • رمز حالة HTTP صحيح: ٤٠٠ لخطأ المُرسِل، ٤٢٢ لفشل تحقّق، ٤٢٩ لتجاوز الحد، ٥٠٠ لخطئك أنت.
  • رمز خطأ نصي ثابت يمكن للكود التفرّع عليه، لا رسالة إنجليزية قد تتغيّر.
  • رسالة تشرح ما يجب فعله لا ما حدث فقط.
  • معرّف طلب في كل استجابة، فهو أول ما تطلبه حين يفتح عميل تذكرة.

رسالة خطأ لا تخبر المطوّر بما يفعله بعدها هي تذكرة دعم مؤجّلة.

الحدود حماية لا عقاب

ضع حداً للمعدّل من أول يوم. أضفه لاحقاً وستكسر عملاء اعتادوا غيابه. أعلن الحد في رؤوس الاستجابة — المتبقي ووقت إعادة التعيين — وأعد `Retry-After` مع ٤٢٩. المطوّر الذي يعرف حدّه يحترمه؛ الذي يكتشفه بالمنع يفتح تذكرة.

المصادقة حسب الحالة

  1. مفتاح API: مناسب للتكامل من خادم إلى خادم، بشرط أن يكون قابلاً للإبطال والتدوير ومحدود الصلاحيات.
  2. OAuth: ضروري حين يتصرّف تطبيق طرف ثالث نيابة عن المستخدم، ومبالغة حين يتكامل العميل مع بياناته هو.
  3. لا تمرّر مفتاحاً في رابط URL أبداً — ينتهي في السجلات وسجل المتصفح.
  4. اعرض آخر استخدام لكل مفتاح، فهو ما يمكّن العميل من حذف القديم بثقة.

التوثيق جزء من المنتج

واجهة بلا مثال قابل للنسخ لن تُستخدم. ولّد التوثيق من تعريف OpenAPI حتى لا ينحرف عن السلوك الفعلي، وضع لكل نقطة نهاية طلباً واستجابة حقيقيين. التوثيق المكتوب يدوياً يصبح خاطئاً خلال شهور، وهو أسوأ من غيابه.

لصيغة أخطاء معيارية بدل اختراع واحدة، RFC 9457 لتفاصيل المشكلة هو ما تتبنّاه الواجهات الجادّة اليوم. ودليل جوجل لتصميم الواجهات أوفى مرجع للتسمية والترقيم والإصدارات، ومواصفة OpenAPI هي ما تولّد منه توثيقك حتى لا ينحرف عن السلوك.

وإن كنت تصمّم واجهة عامة لمنتجك، فالقرارات أعلاه ستلازمك سنوات — راجعها معنا قبل نشر أول نقطة نهاية.

أسئلة شائعة

أين أضع رقم الإصدار؟

في المسار أبسط وأوضح للمطوّرين. الترويسة أنظف نظرياً وأصعب في التصحيح عملياً.

REST أم GraphQL؟

REST لأغلب واجهات المنتجات: أسهل تخزيناً مؤقتاً وتوثيقاً وحدّاً. GraphQL يبرّر تعقيده حين تتنوّع احتياجات القراءة كثيراً.

كم أدعم إصداراً قديماً؟

أعلن سياسة مدة محدّدة مسبقاً — سنة مثلاً — والتزم بها. الغموض هنا يعني أنك لن تحذف إصداراً أبداً.

English version