من التحليل إلى تصميم النظام

مواصفات الواجهات وواجهات برمجة التطبيقات

18 دقيقة الدرس 4 من 10

مواصفات الواجهات وواجهات برمجة التطبيقات

بمجرد تقسيم النظام إلى وحدات ومكونات، تصبح كل نقطة التقاء بين جزأين من البرمجيات مصدر خطر تصميمي. إن لم تُحدَّد نقطة الالتقاء هذه بدقة وكتابة قبل كتابة سطر واحد من الكود، فسيفترض كل طرف افتراضات مختلفة وستفشل عملية التكامل. هذا التعريف الرسمي المكتوب لنقطة الالتقاء يُسمى مواصفة الواجهة. وحين تكون نقطة الالتقاء مكشوفة عبر شبكة (HTTP أو المراسلة أو المقابس)، يُشار إليها عادةً بـ مواصفة API.

يعلّمك هذا الدرس كيفية تأليف هذه العقود: ما الذي يجب أن تتضمنه، وكيف تُهيكلها، وكيف تتحقق من توافقها مع المتطلبات التي جمعتها في وقت سابق من المشروع.

ما تغطيه مواصفة الواجهة

تجيب مواصفة الواجهة الكاملة على ستة أسئلة:

  1. من يستدعي من؟ — حدد المستدعي (العميل) والمُزوِّد (الخادم أو الوحدة).
  2. كيف تتم الاستدعاء؟ — البروتوكول والنقل ونمط الاستدعاء (طلب/استجابة متزامن، رسالة غير متزامنة، استدعاء خلفي، حدث).
  3. ماذا يرسل المستدعي؟ — معامَلات الإدخال: الأسماء وأنواع البيانات والقيود وما إذا كان كل منها إلزامياً أم اختيارياً.
  4. ماذا يُعيد المُزوِّد؟ — حقول الإخراج: الأسماء والأنواع ومعنى كل قيمة في الاستجابة الناجحة.
  5. ماذا يمكن أن يسوء؟ — حالات الخطأ: الأكواد والرسائل والشروط التي تُطلق كل منها.
  6. ما التوقعات غير الوظيفية؟ — اتفاقية مستوى الخدمة للكمون وحد الإنتاجية وطريقة المصادقة وضمان الأمان من التكرار.
مواصفة لا تطبيق. تصف مواصفة الواجهة العقد لا الكود خلفه. يمكن الوفاء بالمواصفة الجيدة من خلال تطبيقات متعددة — نموذج مزيف وأولي وخدمة إنتاجية نهائية، جميعها تُحقق نفس المواصفة. اكتب المواصفة قبل أي تطبيق.

تشريح مواصفة نقطة طرفية REST

تكشف الأنظمة الحديثة عادةً عن واجهات REST عبر HTTP. الهيكل أدناه يُحدد نقطة طرفية واحدة من نظام حجز عيادة حيث تستدعي وحدة الجدولة الأمامية خدمة المواعيد:

POST /api/v1/appointments Authorization: Bearer {access_token} Content-Type: application/json جسم الطلب الحقل | النوع | مطلوب | القيود ------------------|---------|-------|-------------------------------------------- patient_id | integer | نعم | يجب أن يكون موجوداً في جدول المرضى doctor_id | integer | نعم | يجب أن يكون موجوداً في جدول الأطباء appointment_date | string | نعم | تاريخ ISO 8601: YYYY-MM-DD appointment_time | string | نعم | HH:MM (24 ساعة)، ضمن ساعات عمل الطبيب reason | string | لا | 500 حرف كحد أقصى استجابة النجاح 201 Created { "appointment_id": 4821, "status": "confirmed", "confirmation_code": "APT-20240915-4821" } استجابات الخطأ HTTP | error_code | الشرط -----|------------------------|------------------------------------------- 400 | INVALID_DATE_FORMAT | تنسيق appointment_date غير ISO 8601 409 | SLOT_UNAVAILABLE | الطبيب محجوز بالفعل في ذلك الوقت 422 | OUTSIDE_WORKING_HOURS | الوقت خارج جدول الطبيب 404 | DOCTOR_NOT_FOUND | doctor_id غير موجود 401 | UNAUTHORIZED | رمز وصول مفقود أو منتهي الصلاحية

لاحظ أن كل حالة خطأ تمتلك سلسلة error_code مميزة. رسائل عامة مثل "error": "something went wrong" تجبر المطور المستدعي على التخمين؛ أما الأكواد الصريحة فتتيح للمستدعي معالجة كل حالة برمجياً — إعادة المحاولة عند 409، التوجيه لتسجيل الدخول عند 401، عرض رسالة تحقق الحقل عند 400.

مخطط الواجهة: تصوير العقود بين المكونات

مخطط يرسم جميع الواجهات في نظام فرعي لا يُقدَّر بثمن في مراجعات التصميم. يظهر كل مكون كمربع؛ وكل واجهة سهم مُعلَّق يحمل اسم الاستدعاء والبروتوكول. يوضح المخطط أدناه الواجهات الأربع الرئيسية في النظام الفرعي لحجز العيادة:

Interface diagram — Clinic Booking Subsystem Clinic Booking Subsystem — Interface Map Scheduling UI Web Frontend Appointment Service REST API Notification Service Message Queue Availability DB Read Replica Patient Record Service gRPC IF-1: POST /appointments REST · JSON · HTTPS IF-2: Event Async · Queue IF-3: GET /slots REST · JSON IF-4: GetPatient gRPC · Protobuf Sync REST Async Event Sync DB Query Sync gRPC
خريطة الواجهات للنظام الفرعي لحجز العيادة: أربع واجهات مُعرَّفة (IF-1 إلى IF-4) مع المستدعي والمُزوِّد والبروتوكول.

تحصل كل واجهة على معرف فريد يمكن الإشارة إليه في جداول قابلية التتبع ومراجعات التصميم وخطط الاختبار. الخطوط الصلبة تدل على استدعاءات متزامنة؛ والخط المتقطع لـ IF-2 يدل على حدث غير متزامن يُنشر في قائمة انتظار رسائل — المُزوِّد لا ينتظر استجابة.

تحديد الواجهات غير المتزامنة والمدفوعة بالأحداث

في التصميم المدفوع بالأحداث، ينشر المُزوِّد حدثاً ولا ينتظر استجابة. يجب أن توثق المواصفة شكل الحدث بدلاً من مخطط الاستجابة:

EVENT: AppointmentCreated Channel: appointments.created (RabbitMQ exchange, نوع topic) Publisher: Appointment Service Subscribers: Notification Service, Analytics Service الحمولة الحقل | النوع | الوصف -----------------|----------|---------------------------------------- event_id | UUID | معرف فريد (لإلغاء التكرار) event_type | string | دائماً "appointment.created" appointment_id | integer | الموعد المُنشأ حديثاً patient_id | integer | المريض الذي حجز doctor_id | integer | الطبيب المعيَّن appointment_at | ISO 8601 | تاريخ ووقت الموعد كاملاً published_at | ISO 8601 | الطابع الزمني لنشر الحدث الضمانات - التسليم مرة واحدة على الأقل (المشتركون يجب أن يكونوا آمنين من التكرار بناءً على event_id) - قد تُحذف الأحداث الأقدم من 7 أيام من قائمة الرسائل الميتة
مفاتيح الأمان من التكرار في الواجهات غير المتزامنة. لأن قائمة الانتظار قد تُسلِّم نفس الحدث أكثر من مرة أثناء إعادة المحاولات، يجب أن تحمل كل حمولة غير متزامنة event_id فريداً. يتحقق المشتركون مما إذا كانوا قد عالجوا ذلك المعرف بالفعل قبل التصرف. وثِّق هذا الشرط صراحةً في المواصفة — يسهل إغفاله ويصعب إصلاحه بعد النشر.

معايير مواصفة API والأدوات

كتابة المواصفات في نثر حر عرضة للخطأ ويصعب مزامنتها مع الواقع. تحل التنسيقات القابلة للقراءة آلياً المعتمدة في الصناعة هذه المشكلة:

  • OpenAPI 3.x (المعروف سابقاً بـ Swagger) — المعيار السائد لواجهات REST. ملف YAML أو JSON يصف كل نقطة طرفية وجسم الطلب ومخطط الاستجابة وكود الخطأ. أدوات مثل Swagger UI تُحوّله إلى توثيق تفاعلي؛ مولدات الكود تُنتج نماذج عميل بعشرات اللغات.
  • AsyncAPI — نظيرة OpenAPI للتصميم المدفوع بالأحداث. تصف القنوات وحمولات الرسائل والارتباطات لـ Kafka وRabbitMQ وMQTT.
  • Protocol Buffers (ملفات .proto) — لغة المخطط لواجهات gRPC. مكتوبة بصرامة؛ يُطبِّق المحوِّل العقد ويُنشئ كود العميل/الخادم بلغات متعددة.
  • لغة تعريف مخطط GraphQL (SDL) — لواجهات GraphQL، ملف SDL هو المواصفة؛ تُتحقق منها الاستعلامات في وقت البناء.
انجراف المواصفة يُدمر التكامل. المواصفة التي تُكتب مرة واحدة ولا تُحدَّث تصبح عبئاً. تعامل مع المواصفة كوثيقة حية: حدِّثها عند إضافة حقل أو إعادة تسميته أو حذفه، وإصدار API (مثل /api/v1/ مقابل /api/v2/) عند إدخال تغييرات كاسرة. يجب إخطار فرق المستهلكين بالتغييرات الكاسرة قبل النشر.

سجل الواجهات: تتبع جميع العقود في المشروع

في مشروع يضم عشرات المكونات، يُعطي جدول واحد — سجل الواجهات — مدير المشروع والمهندس المعماري صورة كاملة لتبعيات التكامل. كل صف هو واجهة واحدة:

Interface Register table for the online store project Interface Register — Online Store Project ID Caller Provider Operation Protocol Pattern Status IF-01 Cart UI Product Service GET /products/{id} REST / HTTPS Sync Approved IF-02 Checkout UI Order Service POST /orders REST / HTTPS Sync Approved IF-03 Order Service Payment Gateway POST /v1/charges REST / HTTPS Sync In Review IF-04 Order Service Inventory Service StockReserved event RabbitMQ Async Approved IF-05 Inventory Service Supplier API POST /reorder REST / HTTPS Sync Draft IF-06 Shipping Service Courier API POST /shipments REST / HTTPS Sync In Review Approved In Review Draft
سجل الواجهات لمشروع متجر إلكتروني: كل صف هو واجهة واحدة مع المستدعي والمُزوِّد والعملية والبروتوكول ونمط الاستدعاء وحالة الاعتماد.

عمود الحالة (Draft / In Review / Approved) يُظهر فوراً الواجهات التي لا تزال مخاطر غير محلولة. لا يمكن للمشروع الدخول في مرحلة البناء حتى تصل جميع الواجهات التي يعتمد عليها إلى حالة Approved.

من المتطلبات إلى مواصفة الواجهة

يجب أن تتتبع كل مواصفة واجهة إلى متطلب وظيفي واحد أو أكثر. بالنسبة لنقطة الطرف POST /api/v1/appointments في العيادة، تبدو سلسلة القابلية للتتبع هكذا:

  • FR-12: يجب على النظام السماح للمرضى بحجز مواعيد متاحة مع طبيب محدد.
  • FR-13: يجب على النظام منع الحجز المزدوج لطبيب في نفس الفترة الزمنية.
  • NFR-04: يجب أن يستجيب API الحجز خلال 800 ميلي ثانية عند الشريحة المئوية 95 تحت الحمل الطبيعي.

كل متطلب يقود جزءاً محدداً من المواصفة: FR-12 يقود حقول جسم الطلب؛ FR-13 يقود خطأ SLOT_UNAVAILABLE 409؛ NFR-04 يقود اتفاقية مستوى خدمة الكمون الموثقة في قسم المتطلبات غير الوظيفية. حين يتغير متطلب، يعرف المحلل تماماً أي مواصفة واجهة يجب تحديثها — وأي فريق تطوير يجب إخطاره.

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

مواصفة الواجهة المكتوبة جيداً هي واحدة من أكثر المخرجات قيمةً في تحليل الأنظمة. فهي تُزيل مفاجآت التكامل وتُتيح التطوير المتوازي وتُشكِّل أساس حالات اختبار التكامل وتُعدُّ المرجع الموثوق حين تنشأ خلافات بين الفرق بعد أشهر من مرحلة البناء.