Software Engineering22 يوليو 20268 min read

تصميم واجهات API يستمتع المطورون فعلاً باستخدامها

أفضل واجهات API تبدو بديهية. يستعرض هذا الدليل خيارات التصميم التي تحوّل واجهة تقنية إلى شيء يلجأ إليه المطورون مرة تلو الأخرى.

بقلم Innovation T Team


من المرجح أن أفضل واجهة API استخدمتها يوماً جعلتك تشعر وكأنها تقرأ أفكارك. خمّنت اسم نقطة النهاية فوجدتها موجودة. خمّنت اسم الحقل فكان صحيحاً. أخبرتك الأخطاء بالضبط بما حدث من خلل. هذا الشعور ليس محض حظ، بل هو نتاج قرارات تصميم مدروسة اتخذها أشخاص يهتمون بمن يقف على الطرف الآخر من الطلب.

في Innovation T نبني واجهات API وندمجها عبر مشاريع الويب والجوال والسحابة، ويظل الدرس نفسه يطفو على السطح: واجهة API هي منتج، ومستخدموها هم المطورون. تعامل مع وقتهم وانتباههم بالجدية نفسها التي تتعامل بها مع المستخدم النهائي، وسيتبع ذلك التبني الواسع. وإليك كيف تصمم واجهة يستمتع الناس فعلاً باستخدامها.

تسمية متسقة للموارد

واجهة API هي مفردات لغوية. وإذا كانت هذه المفردات غير متسقة، فإن كل نقطة نهاية تتحول إلى اختبار صغير للذاكرة. اختر اصطلاحات واضحة ولا تخالفها أبداً.

استخدم الأسماء للموارد لا الأفعال، فطريقة HTTP تحمل الفعل أصلاً. استعمل أسماء موارد بصيغة الجمع، بأحرف صغيرة، مفصولة بشرطات، وضمّن العلاقات بطريقة يمكن التنبؤ بها:

GET    /v1/customers
GET    /v1/customers/42
GET    /v1/customers/42/invoices
POST   /v1/customers/42/invoices
DELETE /v1/invoices/900

تجنّب الخلط بين userId وuser_id وUserID عبر الحمولات. اختر نمط كتابة واحداً (camelCase أو snake_case) وطبّقه على كل حقل في كل استجابة. الاتساق أثمن من أي خيار مفرد يُقال إنه «أفضل»، لأنه يتيح للمطورين التنبؤ بما لم يقرؤوه بعد.

رموز حالة منطقية

رموز الحالة هي أول إشارة يقرؤها العميل، وغالباً قبل تحليل جسم الاستجابة. استخدمها بأمانة.

  • 200 لعملية قراءة أو تحديث ناجحة.
  • 201 لمورد أنشأته للتو، مع ترويسة Location.
  • 202 عندما تقبل عملاً يكتمل بشكل غير متزامن.
  • 204 لعملية حذف ناجحة بلا جسم استجابة.
  • 400 للمدخلات المشوّهة، و401 لبيانات اعتماد مفقودة أو خاطئة، و403 للمستخدم المصادَق عليه لكن غير المسموح له.
  • 404 لمورد غير موجود، و409 لتعارض مثل التكرار.
  • 422 للطلبات جيدة التكوين التي تفشل في قواعد التحقق.
  • 429 عندما يتجاوز العميل حد المعدل.
  • 500 لأخطائك أنت، لا لأخطاء العميل أبداً.

الخطيئة الكبرى هي إرجاع 200 OK مع خطأ مخبأ داخل الجسم. فهذا يجبر كل عميل على تحليل استجابات النجاح بحذر دفاعي، ويقوّض الغرض كله من رموز الحالة.

أجسام أخطاء مفيدة

رمز الحالة يقول إن شيئاً ما قد فشل، أما جسم الخطأ الجيد فيقول ماذا وأين وكيف يُصلَح. اجعل الأخطاء قابلة للقراءة آلياً وبشرياً في آنٍ واحد:

{
  "error": {
    "type": "validation_error",
    "message": "The request could not be processed.",
    "fields": [
      { "name": "email", "issue": "must be a valid email address" },
      { "name": "age", "issue": "must be greater than or equal to 18" }
    ],
    "requestId": "req_8fa21c"
  }
}

يتيح الحقل type الثابت للعملاء التفريع في الشيفرة. ويساعد الحقل message الإنسان الذي يقرأ السجلات. ويحوّل المصفوف fields رفضاً غامضاً إلى قائمة تحقق قابلة للتنفيذ. ويتيح الحقل requestId للمطور أن يلصق سلسلة نصية واحدة في تذكرة الدعم كي تعثر على الطلب المحدد في سجلاتك. هذا الحقل الواحد يوفّر ساعات على الطرفين.

ترقيم صفحي وترشيح يمكن التنبؤ بهما

أي مجموعة قابلة للنمو يجب أن تُرقَّم صفحياً منذ اليوم الأول. فإضافة الترقيم الصفحي لاحقاً تغيير كاسر يفاجئ الجميع.

الترقيم القائم على المؤشر (cursor) هو الخيار الأكثر متانة لمجموعات البيانات الكبيرة أو المتغيرة بكثرة، لأنه لا يتخطى الصفوف ولا يكرّرها عندما تتبدّل البيانات بين الطلبات:

{
  "data": [
    { "id": "inv_1", "amount": 1200 },
    { "id": "inv_2", "amount": 850 }
  ],
  "pagination": {
    "nextCursor": "eyJpZCI6Imludl8yIn0",
    "hasMore": true
  }
}

يستمر العميل بتمرير ?cursor=... إلى أن تصبح قيمة hasMore خاطئة. أما الترقيم القائم على الإزاحة (?page=3&limit=20) فهو أبسط ومناسب للقوائم الصغيرة المستقرة، لكنه ينحرف حين تُدرَج صفوف أو تُحذف في أثناء التمرير.

يستحق الترشيح القدر نفسه من إمكانية التنبؤ. استخدم معاملات استعلام تُقرأ كلغة واضحة ووثّقها جميعاً: ?status=paid&created_after=2026-01-01&sort=-amount. إشارة الناقص في المقدمة للترتيب التنازلي اصطلاح صغير، لكن ما إن يتعلمه المطور مرة واحدة حتى يعمل في كل مكان من واجهتك.

العمليات مكافئة النتيجة (Idempotency)

تتعطل الشبكات في منتصف الطريق. يرسل العميل طلب دفع، فينقطع الاتصال قبل وصول الاستجابة، ولا يدري العميل إن كان الخصم قد تم أم لا. ومن دون مساعدة، فإن الافتراض الآمن (إعادة المحاولة) يخلق عمليات خصم مكررة.

مفاتيح idempotency تحل هذه المشكلة. يولّد العميل مفتاحاً فريداً ويرسله كترويسة على أي طلب ليس من الآمن بطبيعته تكراره:

POST /v1/charges
Idempotency-Key: 5f2c1a90-payment-42

يخزّن خادمك المفتاح مع نتيجة الطلب الأول. فإن وصل المفتاح نفسه مجدداً، تُرجع الاستجابة الأصلية بدلاً من تنفيذ الإجراء مرتين. إن GET وPUT وDELETE مكافئة النتيجة بحكم تعريفها، أما POST فهو الذي يحتاج إلى هذه الحماية، وتوفيرها يدل على أنك فكّرت بجدية في الموثوقية في ظروف العالم الواقعي. ويزداد هذا أهمية للعملاء المبنيين كتطبيقات جوال تعمل أولاً دون اتصال (انظر /blog/offline-first-mobile-apps)، حيث تُوضع الطلبات في طابور وتُعاد عند عودة الاتصال.

تحديد معدل يتواصل مع العميل

تحمي حدود المعدل بنيتك التحتية، لكن رمز 429 الصامت لا يعلّم المطورين شيئاً. أخبرهم بموقعهم على كل استجابة:

RateLimit-Limit: 1000
RateLimit-Remaining: 12
RateLimit-Reset: 1753142400

وحين ترفض طلباً بالفعل، أدرج ترويسة Retry-After كي يتمكن العملاء من التراجع بلطف بدلاً من إغراقك بالطلبات. العميل حسن السلوك ثمرة شراكة، وأنت تبنيها بمنح العميل المعلومات التي يحتاجها ليتصرف تصرفاً حسناً.

مصادقة تلائم حالة الاستخدام

طابِق الآلية مع المُستدعي. تلائم الرموز الحاملة (bearer tokens) قصيرة العمر (رموز وصول OAuth 2.0 أو JWT) التطبيقات الموجّهة للمستخدمين حيث تنتهي الجلسات وتُجدَّد. وتلائم مفاتيح API عمليات التكامل من خادم إلى خادم حيث يكون السر طويل العمر مقبولاً. وأياً كان اختيارك، فالتزم بثلاث قواعد: اشترط HTTPS في كل مكان، ولا تقبل أبداً بيانات الاعتماد في سلسلة الاستعلام حيث تتسرب إلى السجلات، وأرجِع 401 بسبب واضح عند فشل المصادقة. المصادقة هي حيث تُكسب الثقة أو تُفقد، فاجعلها مملة ويمكن التنبؤ بها.

استراتيجية إدارة الإصدارات

التغيير أمر حتمي. واستراتيجية إدارة الإصدارات هي وعدك بأن التغيير لن يكسر عمليات التكامل القائمة دون سابق إنذار.

إدارة الإصدارات عبر عنوان URL (/v1/، /v2/) هي الأكثر وضوحاً والأسهل استيعاباً، ولهذا تظل الخيار الافتراضي الشائع. أما إدارة الإصدارات عبر الترويسة فتُبقي عناوين URL نظيفة لكنها تخفي الإصدار، فيسهل نسيانه. وأياً كان ما تختاره، فالانضباط أهم من الآلية: التغييرات الإضافية (حقول اختيارية جديدة، نقاط نهاية جديدة) آمنة ولا تتطلب إصداراً جديداً. أما حذف حقل أو إعادة تسميته أو تغيير نوعه فهو تغيير كاسر يستلزم إصداراً جديداً إضافة إلى نافذة إيقاف تدريجي. لا تُعِد أبداً توظيف حقل قائم في الخفاء.

ضمانات الاستقرار

أخبر المطورين بما يمكنهم الاعتماد عليه. انشر أي أجزاء من واجهتك مستقرة، وأيها في مرحلة بيتا، وكم من الوقت سيظل الإصدار الموقوف يعمل قبل إزالته. سياسة إيقاف واضحة، مثل ستة أشهر من الإشعار مع تحذيرات مؤرخة في ترويسات الاستجابة، تحوّل ترحيلاً مخيفاً إلى مهمة مجدولة. سيبني المطورون على واجهة يثقون في بقائها مستقرة بسهولة أكبر بكثير مما يبنون على واحدة قد تتزحزح تحت أقدامهم دون إنذار.

توثيق وأمثلة ممتازة

التوثيق هو حيث يقضي المطورون معظم وقتهم مع واجهتك، ولذلك فهو حيث يؤتي التصميم ثماره أو ينهار. أفضل التوثيقات تشترك في بضع سمات: طلب جاهز للنسخ واللصق لكل نقطة نهاية، ومثال استجابة حقيقي بجانبه، وحقول مُميّزة بوضوح بين الإلزامي والاختياري. اعرض المصادقة مرة واحدة في المقدمة ضمن مقطع قابل للتشغيل. ووفّر بداية سريعة تصل بالمطور إلى أول استدعاء ناجح في أقل من خمس دقائق، لأن هذا النجاح الأول هو ما يحوّل القارئ الفضولي إلى مستخدم ملتزم. والتوثيق التفاعلي الذي يتيح للمرء إطلاق طلب حقيقي من المتصفح يحوّل القراءة إلى تعلّم.

REST والبدائل

REST هو الخيار الافتراضي لسبب وجيه: فهو ينسجم بنظافة مع HTTP، وقابل للتخزين المؤقت، ومفهوم على نطاق عالمي. ويفترض معظم هذا المقال REST لأن معظم واجهات API مبنية عليه.

لكنه ليس الخيار الوحيد. يتيح GraphQL للعملاء طلب الحقول التي يحتاجونها بالضبط في جولة واحدة، وهو ما يتألق مع البيانات الغنية المتشعبة وشاشات التطبيقات التي كانت لولا ذلك ستتفرّع إلى استدعاءات REST كثيرة، على حساب تعقيد التخزين المؤقت وتخطيط استعلامات أثقل على جانب الخادم. أما gRPC فيستخدم Protocol Buffers الثنائية عبر HTTP/2 وهو ممتاز لحركة المرور الداخلية عالية الإنتاجية من خدمة إلى خدمة، وإن كان أقل ملاءمة للمتصفحات والاستكشاف العابر. والخيار الصحيح يعتمد على مستهلكيك. واجهة API عامة لجمهور واسع تميل إلى REST، وتطبيق جوال باحتياجات بيانات معقدة قد يفضّل GraphQL، وأسطول من الخدمات المصغّرة الداخلية قد يوحّد على gRPC. وإذا كنت توازن بين حدود الخدمات وأنماط الاتصال، فإن دليلنا حول الانتقال من /blog/monolith-to-microservices يتعمق أكثر في هذه المفاضلات.

قائمة التحقق لتصميم API

مرّر أي واجهة API جديدة عبر هذه القائمة قبل إطلاقها:

  1. هل سُمّيت الموارد بأسماء متسقة، بصيغة الجمع وبأحرف صغيرة؟
  2. هل نمط كتابة الحقول متطابق عبر كل نقطة نهاية؟
  3. هل يعني كل رمز حالة ما ينبغي أن يعنيه، دون أخطاء مخبأة داخل 200؟
  4. هل تتضمن أجسام الأخطاء نوعاً ثابتاً، ورسالة بشرية، والحقول المخالفة، ومعرّف طلب؟
  5. هل تُرقَّم كل مجموعة قابلة للنمو صفحياً، مع ترشيح وترتيب موثّقين؟
  6. هل العمليات غير الآمنة محمية بمفاتيح idempotency؟
  7. هل تكشف الاستجابات عن ترويسات حد المعدل وعن Retry-After عند الرفض؟
  8. هل تُفرَض المصادقة عبر HTTPS مع إبقاء بيانات الاعتماد خارج عناوين URL؟
  9. هل توجد استراتيجية واضحة لإدارة الإصدارات وسياسة إيقاف منشورة؟
  10. هل يستطيع مطور جديد إجراء استدعاء ناجح من التوثيق في أقل من خمس دقائق؟

جمع الخيوط معاً

كل نقطة أعلاه تعود إلى فكرة واحدة: احترم وقت المطور. التسمية المتسقة تجنّبه إجهاد الذاكرة، ورموز الحالة الأمينة تجنّبه التخمين، والأخطاء المفيدة تجنّبه التنقيح، والعمليات مكافئة النتيجة تجنّبه كوارث التكرار، والتوثيق الجيد يجنّبه الإحباط. افعل ذلك باتساق فتكفّ واجهتك عن كونها تفصيلاً تقنياً وتصير سبباً يدفع الناس لاختيارك.

إذا كان فريقك يصمم واجهة API جديدة، أو يفكّك واجهة قديمة، أو يوازن بين REST وGraphQL وgRPC، فبإمكان Innovation T مساعدتك على إرساء الأسس الصحيحة. اكتشف طريقة عملنا على صفحة الخدمات، أو تواصل معنا لمناقشة مشروعك.

#تصميم API#REST#تجربة المطور#هندسة البرمجيات

جاهز للبناء مع Innovation T؟

سواء كان الأمر يتعلق بالأمن أو النمو أو الهندسة، يمكن لفريقنا مساعدتك على تنفيذه بإتقان.