API قابلة للتوسع لا تعني عدد endpoints كبيرًا أو architecture معقدة. البداية هي عقد واضح: ما الموارد؟ كيف تُعرّف؟ ما العمليات المسموحة؟ ما شكل الخطأ؟ عندما تكون هذه القواعد ثابتة، يستطيع أكثر من client البناء عليها بدون معرفة تفاصيل قاعدة البيانات. التصميم الجيد يقلل المفاجآت ويجعل التغيير التدريجي ممكنًا.
صمم حول Resources لا أفعال داخل URL
استخدم nouns مثل /users و/orders بدل /createUser و/getOrder عندما يناسب نموذج REST. HTTP method تعبر عن العملية، وال resource ID تحدد العنصر. ليست قاعدة مقدسة لكل حالة، لكنها تقلل تنوع patterns داخل API.
اجعل الأخطاء عقدًا قابلًا للبرمجة
لا ترسل message نصية فقط. استخدم code ثابتة، message بشرية، وربما details للحقول. client تعتمد على code لا على مقارنة النص. لا تسرب stack traces أو SQL أو secrets.
خطوات عملية
- اختر status مناسب.
- أرسل error code ثابتة.
- أضف تفاصيل validation.
- ضع request/trace ID.
- سجل التفاصيل الحساسة في الخادم فقط.
Pagination من البداية
endpoint تعيد كل rows تعمل في التطوير ثم تنهار مع البيانات. اختر cursor pagination للقوائم المتغيرة أو offset في الحالات البسيطة، وحدد limit قصوى. أعد metadata كافية لل client بدون count مكلفة إذا لم تحتاجها.
Filtering و Sorting تحتاج allowlist
لا تحول query مباشرة إلى اسم column أو SQL. عرّف fields المسموحة وأنواعها واتجاه sort. هذا يحسن الأمان ويمنع API من الارتباط بكل تفاصيل schema الداخلية.
Idempotency للعمليات الحساسة
عمليات الدفع أو إنشاء resource من clients متصلة بشبكة غير مستقرة تحتاج Idempotency Key أو معرفًا منطقيًا يمنع duplicate side effects. Retry يجب أن تكون متوقعة ومختبرة.
Versioning لا يعني /v2 لكل تعديل
أضف fields اختيارية بطريقة backward-compatible عندما تستطيع. اكسر العقد فقط عندما تحتاج، ووثق deprecation ومدة الانتقال. يمكن استخدام path أو header versioning حسب المؤسسة؛ الأهم consistency.
Authentication و Authorization منفصلتان
إثبات هوية caller لا يعني أنها تملك resource. طبق checks على كل عملية و scope أو role، ولا تعتمد على إخفاء endpoint من UI.
قائمة مراجعة
- Resource model واضح.
- Error contract ثابت.
- Pagination موجودة.
- Filters allowlisted.
- Idempotency للعمليات اللازمة.
- AuthZ على resource.
- OpenAPI/tests متزامنة مع التنفيذ.
تعامل مع Concurrency صراحة
تحديث نفس resource من عميلين قد يؤدي إلى lost update. استخدم version field أو ETag/If-Match أو transaction مناسبة، وأعد 409/412 حسب العقد عندما يكتب client على نسخة قديمة. لا تجعل آخر request يفوز بصمت إذا كان فقدان التعديل مؤثرًا.
Observability جزء من عقد التشغيل
أضف request ID أو trace ID، metrics لل latency والأخطاء، و structured logs لا تحتوي secrets. عندما يقول client إن API فشلت، يجب أن تستطيع ربط الطلب بخطأ داخلي بدون مطالبة المستخدم بإرسال كامل payload الحساسة. راقب p95/p99 لا المتوسط فقط.
شارك في تقييم ونقاش المقال
رأيك يضيف قيمة للمقال ويساعدنا على تحسين المحتوى والنقاش حوله.
النقاش
جارٍ تحميل التعليقات…