ملخص سريع
يعني نهج "التصميم أولاً" أن مواصفات واجهة برمجة التطبيقات (API) تُكتب قبل كود التنفيذ، وأنها تصبح مصدر الحقيقة الذي تُشتق منه النماذج الوهمية، والتوثيق، والاختبارات، ومقاطع العملاء. إذا اخترت منصة تدعم هذا التدفق من البداية إلى النهاية، ستقلل مشكلة شائعة: اختلاف الكود عن الوثائق. تشرح هذه المقالة كيف تطبق "التصميم أولاً" عمليًا، وما الذي يجب أن تبحث عنه في الأدوات، وكيف يمكن استخدام Apidog كمنصة تعتمد هذا النهج.
مقدمة
يتعلم معظم المطورين بناء واجهات برمجة التطبيقات باستخدام نهج "الكود أولاً": تكتب المسار، تضيف بعض التعليقات التوضيحية، تشغل مولّدًا، ثم تحصل على التوثيق. يعمل ذلك في البداية، لكنه غالبًا يتعطل مع نمو المشروع.
المشكلة المعتادة هي انجراف الوثائق. يغيّر مهندس تنسيق الاستجابة، لكن لا يحدّث التعليقات أو التعريفات. بعد عدة أشهر، تقول الوثائق إن الاستجابة مصفوفة من سلاسل نصية، بينما ترجع الواجهة فعليًا مصفوفة كائنات تحتوي على الحقل value.
نهج "التصميم أولاً" يعكس العملية: المواصفات هي المصدر الأساسي، والكود والتوثيق والنماذج الوهمية والاختبارات تُبنى حولها. عندما تتغير المواصفات، يجب أن يتغير كل شيء معها.
عمليًا، يساعد هذا النهج الفرق على:
- تقليل مفاجآت التكامل.
- تمكين الواجهة الأمامية من البدء مبكرًا باستخدام mock server.
- جعل التوثيق جزءًا من العقد، لا ناتجًا ثانويًا.
- اكتشاف التغييرات المدمرة قبل وصولها للإنتاج.
لكن نجاح "التصميم أولاً" يعتمد على الأداة. إذا كان تعريف نقطة نهاية في أداة المواصفات يستغرق 20 دقيقة بينما كتابة route handler تستغرق 5 دقائق، فلن يلتزم الفريق بالعملية. يجب أن تجعل الأداة كتابة المواصفات أسرع وأسهل، لا عبئًا إضافيًا.
ماذا يعني "التصميم أولاً" عمليًا؟
"التصميم أولاً" ليس تقنية محددة، بل سير عمل. يمكن تطبيقه على REST باستخدام OpenAPI، أو GraphQL بأسلوب schema-first، أو gRPC باستخدام ملفات proto.
1. قبل كتابة الكود
ابدأ بتعريف واجهة API كمواصفة OpenAPI. يجب أن تتضمن على الأقل:
- مسارات نقاط النهاية وطرق HTTP.
- معاملات الطلب: path، query، header.
- مخطط جسم الطلب لـ
POSTوPUTوPATCH. - مخططات الاستجابة لكل رموز الحالة المهمة مثل
200و400و401و422و500. - متطلبات المصادقة.
- أوصاف الحقول وأمثلة عملية.
مثال مبسط لمواصفة OpenAPI:
paths:
/users/{id}:
get:
summary: Get user by ID
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
"200":
description: "User profile"
content:
application/json:
schema:
$ref: "#/components/schemas/UserProfile"
"404":
description: "User not found"
components:
schemas:
UserProfile:
type: object
required:
- id
- email
properties:
id:
type: integer
example: 123
email:
type: string
format: email
example: user@example.com
في هذه المرحلة، تُحسم القرارات المهمة: التسمية، هيكل البيانات، نمط الأخطاء، الترقيم، والمصادقة.
2. أثناء التطوير
بعد حفظ المواصفات، انشرها على mock server. بذلك يمكن لفريق الواجهة الأمامية بناء التكامل قبل جاهزية الواجهة الخلفية.
مثال استخدام من الواجهة الأمامية:
const response = await fetch("https://mock.example.com/users/123");
const user = await response.json();
console.log(user.email);
في الوقت نفسه، ينفذ فريق الواجهة الخلفية بناءً على نفس المواصفات. هنا تصبح المواصفات وثيقة المتطلبات التقنية.
3. بعد التنفيذ
شغّل اختبارات تتحقق من أن الاستجابة الفعلية تطابق المخطط.
مثال على الفكرة:
// pseudo-code
expect(response.status).toBe(200);
expect(response.body).toMatchSchema(UserProfileSchema);
أي اختلاف بين التنفيذ والمواصفات يجب أن يفشل الاختبار. هذا ما يمنع انجراف العقد بمرور الوقت.
4. عند تغير المتطلبات
لا تبدأ بتعديل الكود مباشرة. اتبع الترتيب التالي:
- حدّث المواصفات.
- راجع التغيير مع الواجهة الأمامية والخلفية.
- حدّث النموذج الوهمي.
- حدّث التنفيذ.
- شغّل اختبارات التحقق من المطابقة.
بهذا تبقى المواصفات مصدر الحقيقة.
ما الذي تحتاجه منصة "التصميم أولاً"؟
ليست كل أدوات API مناسبة لهذا الأسلوب. الأداة الجيدة يجب أن تدعم الخطوات العملية التالية.
محرر API مرئي
كتابة YAML يدويًا مفيدة أحيانًا، لكنها ليست أفضل واجهة تصميم يومية لكل الفريق. المحرر المرئي يجب أن يسمح لك بتعريف:
- المسار والطريقة.
- معاملات الطلب.
- جسم الطلب.
- الاستجابات.
- المخططات المشتركة.
- القيود والأمثلة.
وفي الخلفية يجب أن ينتج OpenAPI صالحًا.
تحقق فوري من OpenAPI
يجب اكتشاف أخطاء المواصفات أثناء التحرير، لا عند توليد الكود أو تشغيل mock server. أمثلة على الأخطاء التي يجب التقاطها:
-
schemaغير صالح. -
$refيشير إلى مكون غير موجود. - response بدون description.
- نوع حقل غير مطابق للقيمة المثال.
Mock server مولّد من المواصفات
اكتب المواصفات، واحصل على mock endpoint مباشرة. يجب أن يحترم mock server:
- أنواع الحقول.
- التنسيقات مثل
emailوdate-time. - قيود
minimumوmaximum. - قيم
enum. - الكائنات والمصفوفات المتداخلة.
- المكونات المشار إليها باستخدام
$ref.
توثيق قابل للمعاينة
يجب أن ترى التوثيق كما سيظهر للمستهلكين قبل نشره. هذا مفيد لمراجعة:
- وضوح أسماء الحقول.
- أمثلة الطلبات والاستجابات.
- رسائل الخطأ.
- طريقة المصادقة.
مراجعة الفريق
تعامل مع تغييرات مواصفات API مثل تغييرات الكود. تحتاج إلى:
- تعليقات على نقاط النهاية أو الحقول.
- سجل تغييرات.
- مراجعة قبل اعتماد التغيير.
- وضوح حول من غيّر ماذا ومتى.
تصدير OpenAPI قياسي
لا يجب أن تكون المواصفات محبوسة داخل أداة واحدة. يجب أن تستطيع تصديرها كـ OpenAPI 3.x لاستخدامها مع:
- مولّدات الكود.
- بوابات API.
- أدوات الاختبار.
- أدوات التوثيق.
- أدوات الحوكمة.
Apidog كمنصة تعتمد "التصميم أولاً"
تم بناء Apidog حول فكرة أن المواصفات هي الأثر الأساسي. التصميم، والنماذج الوهمية، والاختبارات، والتوثيق، ومراجعة الفريق كلها تعمل فوق تعريف API نفسه.
محرر OpenAPI مرئي
في Apidog، يمكنك تعريف كل endpoint عبر نموذج منظم بدل كتابة YAML يدويًا:
- path
- method
- parameters
- request body
- responses
- schema fields
- validation rules
- examples
إذا كنت تفضل التحرير الخام، يوفر Apidog عرض YAML أو JSON للمواصفات. التغييرات في العرض المرئي والعرض الخام تتزامن معًا.
استخدم المكونات المشتركة لتقليل التكرار. مثلًا، عرّف مخططًا واحدًا باسم UserProfile ثم أعد استخدامه في أكثر من endpoint باستخدام $ref.
مثال:
components:
schemas:
ErrorResponse:
type: object
required:
- code
- message
properties:
code:
type: string
example: USER_NOT_FOUND
message:
type: string
example: User was not found
ثم استخدمه في الاستجابات:
responses:
"404":
description: User not found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
معاينة التوثيق في الوقت الفعلي
أثناء تصميم endpoint، يتم تحديث عرض التوثيق. استخدم المعاينة للتحقق من:
- هل وصف الحقول مفهوم؟
- هل أمثلة الاستجابة واقعية؟
- هل رموز الأخطاء واضحة؟
- هل يمكن لفريق الواجهة الأمامية فهم العقد دون سؤال إضافي؟
يمكنك مشاركة رابط التوثيق مع مديري المنتجات أو قادة الواجهة الأمامية أثناء مرحلة التصميم للمراجعة، دون الحاجة إلى تثبيت أداة محلية.
النماذج الوهمية الذكية
عند حفظ endpoint في Apidog، يكون mock server جاهزًا للاستخدام. يولّد بيانات استجابة بناءً على المخططات.
أمثلة:
- الحقول من النوع
stringمعformat: emailتعيد بريدًا إلكترونيًا صالحًا. - الحقول الرقمية مع
minimumوmaximumتعيد قيمًا ضمن النطاق. - حقول
enumتعيد قيمة من القيم المسموحة. - الكائنات والمصفوفات المتداخلة تتبع بنية المخطط.
- المكونات باستخدام
$refيتم حلها ومحاكاتها.
يمكن أيضًا إعداد قواعد mock مخصصة، مثل:
- إرجاع
404عندما يكون path parameter يساوي0. - إرجاع payload محدد عند قيمة معينة في query parameter.
- اختبار حالات الخطأ بدون انتظار تنفيذ الواجهة الخلفية.
مراجعة الفريق وتتبع التغييرات
تغييرات مواصفات API في Apidog تكون مرئية لأعضاء مساحة العمل. يمكن إضافة تعليقات على endpoints أو حقول محددة، كما يساعد سجل التغييرات على معرفة من عدّل ماذا ومتى.
هذا يجعل مراجعة مواصفات API جزءًا من سير العمل الطبيعي بدل أن تكون ملفًا منفصلًا ينساه الفريق.
"التصميم أولاً" مقابل "الكود أولاً": المقايضات الفعلية
نهج "التصميم أولاً" ليس مناسبًا لكل حالة. هذه مقارنة عملية.
مزايا "التصميم أولاً"
- يمكن للواجهة الأمامية والخلفية العمل بالتوازي.
- التوثيق أدق لأنه المصدر، وليس ناتجًا ثانويًا.
- مشاكل التكامل تظهر مبكرًا أثناء مراجعة التصميم.
- عقود API صريحة وقابلة للاختبار.
- تغييرات API تمر بعملية مراجعة افتراضيًا.
عيوب "التصميم أولاً"
- يحتاج وقتًا مبدئيًا لتعريف المواصفات.
- يتطلب تعلم أدوات المواصفات.
- يحتاج انضباطًا للحفاظ على توافق التنفيذ مع المواصفات.
- الإفراط في تحديد التفاصيل مبكرًا قد يقيدك قبل فهم المجال جيدًا.
مزايا "الكود أولاً"
- أسرع في النماذج الأولية والمشاريع الصغيرة.
- مناسب للمطور الفردي الذي يكرر بسرعة.
- لا يتطلب تعلم أداة مواصفات منفصلة.
عيوب "الكود أولاً"
- التوثيق يميل إلى الانجراف.
- الواجهة الأمامية غالبًا تنتظر الواجهة الخلفية.
- العقد يكون ضمنيًا، ما يجعل التغييرات المدمرة أصعب في الاكتشاف.
- إعادة هيكلة API تتطلب تحديثات يدوية للتوثيق.
كقاعدة عملية: إذا كان أكثر من مهندس يعمل على نفس API، أو كان هناك تنسيق واضح بين الواجهة الأمامية والخلفية، فإن "التصميم أولاً" غالبًا يستحق الاستثمار.
أدوات تدعم سير عمل "التصميم أولاً"
Apidog
منصة تعتمد "التصميم أولاً" وتجمع بين المحرر المرئي، والنماذج الوهمية، والتوثيق، والاختبار، ومراجعة الفريق في أداة واحدة. يناسب الفرق التي تريد تقليل التنقل بين أدوات متعددة أثناء دورة حياة API.
Stoplight Studio
محرر OpenAPI قوي مع دعم Spectral لفرض قواعد النمط. مناسب للمؤسسات التي تركز على الحوكمة. لا يوفر نفس مستوى التكامل الكامل بين التصميم والاختبار والنماذج الوهمية في أداة واحدة.
SwaggerHub
منصة ناضجة لتحرير OpenAPI والتعاون عليها، ومستخدمة في بيئات مؤسسية كثيرة. مناسبة للفرق الموجودة بالفعل في نظام Swagger البيئي. قدرات النماذج الوهمية والاختبار أقل مركزية مقارنة بأدوات التصميم المتكاملة.
Postman مع API Builder
يوفر Postman تبويبًا لتصميم API وإنشاء مواصفات OpenAPI، لكن سير العمل بين التصميم والمجموعات قد يبدو منفصلًا. إنشاء mock server يتطلب إعدادًا إضافيًا مقارنة بالتوليد المباشر من المواصفات. يناسب فرق "الكود أولاً" التي تريد إضافة طبقة توثيق وتصميم تدريجيًا.
Insomnia مع وضع المستند
يدعم تحرير مواصفات OpenAPI ويوفر نماذج وهمية أساسية. مناسب للمطورين الفرديين أو الفرق الصغيرة التي تريد خيارًا خفيفًا.
إعداد سير عمل "التصميم أولاً" في Apidog
اتبع هذه الخطوات لتطبيق النهج داخل فريقك.
الخطوة 1: ابدأ بالمواصفات، لا بالمجموعة
أنشئ مشروعًا جديدًا وافتح تبويب التصميم. قبل إرسال أي طلب، عرّف على الأقل:
- path
- method
- response schema
- status codes
- error response
الهدف هو توضيح العقد قبل التنفيذ.
الخطوة 2: عرّف المكونات المشتركة أولًا
قبل إضافة كل endpoints، أنشئ مخططات مشتركة مثل:
ErrorResponsePaginationUserProfileAuthTokenValidationError
هذا يقلل التكرار ويمنع اختلاف تنسيق الأخطاء أو الترقيم بين endpoints.
مثال:
components:
schemas:
Pagination:
type: object
properties:
page:
type: integer
example: 1
pageSize:
type: integer
example: 20
total:
type: integer
example: 135
الخطوة 3: أنشئ mock URL مبكرًا
بعد حفظ endpoint، انسخ mock URL وشاركه مع فريق الواجهة الأمامية. يمكنهم البدء في بناء الواجهة باستخدام العقد المتفق عليه.
مثال:
const res = await fetch(`${MOCK_API_BASE_URL}/users?page=1`);
const data = await res.json();
الخطوة 4: راجع التوثيق قبل كتابة الكود
افتح معاينة التوثيق واسأل:
- هل يعرف المستهلك ما الذي يرسله؟
- هل يعرف ما الذي سيستقبله؟
- هل حالات الخطأ واضحة؟
- هل الأمثلة كافية لاستخدام endpoint مباشرة؟
إذا كان الوصف غير واضح في التوثيق، أصلحه في المواصفات قبل التنفيذ.
الخطوة 5: ثبّت المواصفات قبل بدء التنفيذ
بعد انتهاء مراجعة التصميم، تعامل مع المواصفات كعقد للسبرنت. إذا احتاج التنفيذ إلى تغيير العقد، لا تعدّل الكود بصمت. اتبع المسار التالي:
- افتح تعديلًا في المواصفات.
- أضف تعليقًا يشرح السبب.
- احصل على موافقة الفريق المعني.
- حدّث mock والتوثيق.
- حدّث التنفيذ.
الخطوة 6: شغّل اختبارات التحقق في CI
أضف اختبارات تتحقق من أن الاستجابات الفعلية تطابق المخططات. الهدف هو منع الانحراف بين الكود والمواصفات.
الفكرة العامة:
# مثال توضيحي لسير CI
npm test
npm run api-contract-test
الاختبار يجب أن يفشل إذا:
- حقل مطلوب غير موجود.
- نوع الحقل مختلف.
- قيمة enum خارج القيم المسموحة.
- status code غير موثق.
- بنية الخطأ لا تطابق المخطط.
الأسئلة الشائعة
هل "التصميم أولاً" مخصص فقط لواجهات REST؟
لا. المبدأ ينطبق على أي بروتوكول يمكن تعريف عقد له. في REST تستخدم OpenAPI. في GraphQL يمكنك استخدام schema-first. في gRPC تؤدي ملفات proto نفس الدور. يدعم Apidog تصميم REST و GraphQL، بينما تؤدي ملفات proto دور العقد أولًا في gRPC.
هل يجب تعريف كل endpoints قبل بدء التطوير؟
لا. يمكنك تطبيق "التصميم أولاً" على مستوى الميزة. قبل بناء ميزة معينة، عرّف مواصفاتها، حتى لو كانت أجزاء أخرى من النظام لا تزال تعتمد "الكود أولاً". التبني التدريجي عملي جدًا.
كيف يعمل هذا النهج مع Agile؟
اجعل مراجعة مواصفات API جزءًا من بداية السبرنت. في التخطيط، يراجع الفريق العقد. أثناء السبرنت، تعمل الواجهة الأمامية ضد mock server وتنفذ الواجهة الخلفية ضد المواصفات. في النهاية، تتحقق الاختبارات من التطابق.
ماذا لو احتاج التنفيذ إلى الانحراف عن المواصفات؟
هذا يحدث. الإجراء الصحيح هو تحديث المواصفات أولًا، ثم مراجعة التغيير مع أصحاب المصلحة، خصوصًا فريق الواجهة الأمامية، ثم تعديل التنفيذ. لا تجعل التنفيذ يصبح مصدر الحقيقة دون قصد.
هل يمكن توليد server stubs من تصدير OpenAPI الخاص بـ Apidog؟
نعم. صدّر المواصفات من Apidog كـ OpenAPI 3.x، ثم استخدم أداة قياسية مثل openapi-generator لإنشاء server stubs. يدعم openapi-generator العديد من اللغات وأطر العمل.
كيف نتعامل مع ترقيم إصدارات المواصفات؟
يمكن استخدام سجل التغييرات داخل المشروع لتتبع التعديلات. للتغييرات الكبيرة التي تتطلب تشغيل إصدارين بالتوازي، مثل v1 و v2، استخدم مشاريع أو فروعًا منفصلة حسب طريقة عمل الفريق.
الخلاصة
"التصميم أولاً" يتطلب انضباطًا مبدئيًا، لكنه يقلل تكلفة التكامل لاحقًا. أهم قاعدة: اجعل المواصفات مصدر الحقيقة، ثم ابنِ حولها mock server، والتوثيق، والاختبارات، والتنفيذ.
إذا كانت كتابة المواصفات مؤلمة، سيتجاوزها الفريق. لذلك يجب أن تجعل الأداة التصميم سريعًا وعمليًا. يوفر Apidog محررًا مرئيًا، ونماذج وهمية فورية، ومعاينة توثيق، وسير مراجعة يساعد على جعل "التصميم أولاً" جزءًا طبيعيًا من بناء واجهات API.
Top comments (0)