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

واجهة برمجة التطبيقات (API) (واجهة برمجة التطبيقات) هي عقد بين مزود الخدمة وعملائه. تعتبر واجهة برمجة التطبيقات (API) المصممة جيدًا بديهية ومتسقة وسهلة الاستخدام. تؤدي واجهة برمجة التطبيقات (API) سيئة التصميم إلى إحباط المطورين وزيادة عبء الدعم ونقاط الضعف الأمنية والتغييرات الباهظة التكلفة.
مقدمة
واجهة برمجة التطبيقات (API) (واجهة برمجة التطبيقات) هي عقد بين مزود الخدمة وعملائه. تعتبر واجهة برمجة التطبيقات (API) المصممة جيدًا بديهية ومتسقة وسهلة الاستخدام. تؤدي واجهة برمجة التطبيقات (API) سيئة التصميم إلى إحباط المطورين وزيادة عبء الدعم ونقاط الضعف الأمنية والتغييرات الباهظة التكلفة.
واجهات برمجة التطبيقات (APIs) عبارة عن منتجات - قم بتصميمها بنفس العناية التي تتمتع بها واجهات المستخدم. سواء كنت تقوم ببناء REST أو GraphQL أو gRPC، تظل مبادئ التصميم الجيد لواجهة برمجة التطبيقات (API) ثابتة.
مبادئ تصميم واجهة برمجة تطبيقات RESTful
1. استخدم الأسماء للموارد
الموارد هي الكيانات الأساسية في نظامك. سميها بالأسماء وليس بالأفعال:
✅ GET /users — List users
✅ GET /users/123 — Get user by ID
✅ POST /users — Create user
✅ PATCH /users/123 — Partially update user
✅ PUT /users/123 — Replace user
✅ DELETE /users/123 — Delete user
❌ GET /getUser — Verb in URL
❌ POST /createUser — Verb in URL
❌ POST /users/create — Verb in URL path
❌ GET /users?action=delete — Action as query parameter
2. استخدم أساليب HTTP المناسبة
| الطريقة | الغرض | عاجز | آمنة | الجسم |
|---|---|---|---|---|
| الحصول على | استرداد أحد الموارد | نعم | نعم | لا |
| ** مشاركة ** | إنشاء مورد | لا | لا | نعم |
| ضع | استبدال كامل | نعم | لا | نعم |
| ** التصحيح ** | تحديث جزئي | لا | لا | نعم |
| حذف | إزالة أحد الموارد | نعم | لا | اختياري |
Idempotent: تؤدي الطلبات المتطابقة المتعددة إلى نفس نتيجة طلب واحد.
آمن: لا توجد آثار جانبية — يمكن تخزينها مؤقتًا وتكرارها بأمان.
3. اصطلاحات التسمية المتسقة
naming_rules:
- "Use plural nouns: /users, /orders, /products"
- "Use kebab-case for multi-word: /order-items, /shipping-addresses"
- "Use lowercase throughout"
- "Nest resources logically: /users/123/orders"
- "Avoid deep nesting (max 2-3 levels)"
- "Use query parameters for filtering, sorting, pagination"
مثال التعشيش:
/users/123/orders — Orders belonging to user 123
/users/123/orders/456 — Specific order
/users/123/orders/456/items — Items in that order (okay)
/users/123/orders/456/items/789/details (too deep!)
4. إصدار API الخاص بك
يجب أن تؤدي التغييرات العاجلة إلى زيادة الإصدار:
إصدار URI (الأكثر شيوعًا):
https://api.example.com/v1/users
https://api.example.com/v2/users
إصدار الرأس:
Accept: application/vnd.example.v1+json
لا تقم مطلقًا بكسر التوافق مع الإصدارات السابقة داخل نفس الإصدار ما لم:
- هناك ثغرة أمنية خطيرة.
- لديك سياسة الإهمال وقمت بإبلاغها.
- المستخدمون المتأثرون داخليون فقط.
5. استخدم رموز حالة HTTP ذات مغزى
2xx Success:
200 OK: Generic success (GET, PATCH)
201 Created: Resource created (POST)
204 No Content: Success, no response body (DELETE)
3xx Redirection:
301 Moved Permanently
304 Not Modified (caching)
4xx Client Error:
400 Bad Request: Malformed request, validation error
401 Unauthorized: Missing or invalid authentication
403 Forbidden: Authenticated but not authorized
404 Not Found: Resource does not exist
405 Method Not Allowed: Wrong HTTP method
409 Conflict: Resource state conflict (duplicate, version mismatch)
422 Unprocessable Entity: Semantic validation failure
429 Too Many Requests: Rate limit exceeded
5xx Server Error:
500 Internal Server Error: Unexpected server failure
502 Bad Gateway: Upstream service failed
503 Service Unavailable: Temporary overload/maintenance
504 Gateway Timeout: Upstream service timed out
تصميم الطلب والاستجابة
مغلف استجابة متسقة
{
"data": {
"id": "user_123",
"email": "john@example.com",
"name": "John Doe",
"created_at": "2024-01-15T10:30:00Z"
},
"meta": {
"request_id": "req_abc123",
"timestamp": "2024-01-15T10:30:00Z"
}
}
ردود الأخطاء
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The request body contains validation errors",
"details": [
{
"field": "email",
"message": "Email is required",
"code": "REQUIRED_FIELD"
},
{
"field": "age",
"message": "Age must be between 18 and 120",
"code": "INVALID_VALUE",
"constraints": {
"minimum": 18,
"maximum": 120
}
}
]
}
}
ترقيم الصفحات
GET /users?page=2&per_page=20&sort=created_at:desc
{
"data": [ ... ],
"meta": {
"page": 2,
"per_page": 20,
"total": 100,
"total_pages": 5,
"count": 20
},
"links": {
"first": "/users?page=1&per_page=20",
"prev": "/users?page=1&per_page=20",
"next": "/users?page=3&per_page=20",
"last": "/users?page=5&per_page=20"
}
}
ترقيم الصفحات المستند إلى المؤشر (موصى به لمجموعات البيانات الكبيرة):
GET /users?cursor=eyJpZCI6IDUwMH0=&limit=20
{
"data": [ ... ],
"meta": {
"next_cursor": "eyJpZCI6IDUyMH0=",
"has_more": true
}
}
التصفية والفرز والبحث
// Filtering
GET /users?role=admin&status=active
GET /orders?created_at[gte]=2024-01-01&total[gt]=100
// Sorting
GET /users?sort=name:asc,created_at:desc
// Searching
GET /users?search=john
// Field selection (sparse fields)
GET /users/123?fields=id,name,email
التحديثات الجزئية (التصحيح مقابل PUT)
// PUT — Full replacement (requires all fields)
PUT /users/123
{
"email": "newemail@example.com",
"name": "John Updated",
"age": 31
}
// PATCH — Partial update (only send changed fields)
PATCH /users/123
{
"email": "newemail@example.com"
}
أفضل الممارسات الأمنية
المصادقة
موصى به: OAuth 2.0 + OpenID Connect
POST /oauth/token
Content-Type: application/json
{
"grant_type": "client_credentials",
"client_id": "your_client_id",
"client_secret": "your_client_secret",
"scope": "read write"
}
Response:
{
"access_token": "eyJhbGciOi...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "read write"
}
GET /api/users
Authorization: Bearer eyJhbGciOi...
هيكل JWT
// Header
{
"alg": "RS256",
"typ": "JWT"
}
// Payload
{
"sub": "user_123",
"iss": "auth.example.com",
"iat": 1705312200,
"exp": 1705315800,
"scope": "read:users write:users",
"roles": ["admin"]
}
الحد من المعدل
HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1705315800
HTTP/1.1 429 Too Many Requests
Retry-After: 3600
Content-Type: application/json
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Try again in 3600 seconds.",
"retry_after": 3600
}
}
التحقق من صحة الإدخال
// Zod validation schema for API input
import { z } from 'zod';
const createUserSchema = z.object({
email: z.string().email('Invalid email format'),
name: z.string().min(1, 'Name is required').max(100),
age: z.number().int().min(18).max(120).optional(),
role: z.enum(['user', 'admin', 'moderator']).default('user'),
tags: z.array(z.string()).max(10).optional(),
});
// Validation middleware
function validate(schema: ZodSchema) {
return (req, res, next) => {
const result = schema.safeParse(req.body);
if (!result.success) {
return res.status(422).json({
error: {
code: 'VALIDATION_ERROR',
message: 'Validation failed',
details: result.error.issues.map(i => ({
field: i.path.join('.'),
message: i.message
}))
}
});
}
req.validatedBody = result.data;
next();
};
}
HTTPS وCORS
// CORS configuration
const corsOptions = {
origin: [
'https://app.example.com',
'https://admin.example.com',
],
methods: ['GET', 'POST', 'PATCH', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
exposedHeaders: ['X-RateLimit-Remaining'],
credentials: true,
maxAge: 86400 // Preflight cache (24 hours)
};
app.use(cors(corsOptions));
وثائق واجهة برمجة التطبيقات
مواصفات OpenAPI 3.0
openapi: 3.0.3
info:
title: User Management API
version: 2.0.0
description: API for managing users in the system
contact:
email: api-support@example.com
servers:
- url: https://api.example.com/v2
description: Production server
paths:
/users:
get:
summary: List all users
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: per_page
in: query
schema:
type: integer
default: 20
maximum: 100
responses:
'200':
description: A list of users
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
meta:
$ref: '#/components/schemas/PaginationMeta'
post:
summary: Create a new user
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
responses:
'201':
description: User created
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'422':
description: Validation error
components:
schemas:
User:
type: object
properties:
id:
type: string
email:
type: string
format: email
name:
type: string
created_at:
type: string
format: date-time
التوثيق التفاعلي
# Serve Swagger UI for API documentation
npm install -g swagger-ui-express
# Visit: https://api.example.com/docs
اختبار واجهة برمجة التطبيقات
اختبار العقد
// Pact consumer-driven contract test
const { Pact } = require('@pact-foundation/pact');
describe('User API contract', () => {
const provider = new Pact({
consumer: 'Frontend App',
provider: 'User Service',
port: 1234,
});
beforeAll(() => provider.setup());
describe('GET /users/123', () => {
beforeAll(() => {
return provider.addInteraction({
state: 'User 123 exists',
uponReceiving: 'a request for user 123',
withRequest: {
method: 'GET',
path: '/users/123',
headers: { Authorization: 'Bearer valid-token' }
},
willRespondWith: {
status: 200,
headers: { 'Content-Type': 'application/json' },
body: {
data: {
id: '123',
email: 'user@example.com',
name: 'Test User'
}
}
}
});
});
it('returns the user', async () => {
const response = await fetch('http://localhost:1234/users/123', {
headers: { Authorization: 'Bearer valid-token' }
});
expect(response.status).toBe(200);
});
afterEach(() => provider.verify());
});
afterAll(() => provider.finalize());
});
GraphQL مقابل REST
| الجانب | راحة | GraphQL |
|---|---|---|
| ** جلب البيانات ** | نقاط نهاية متعددة، استجابة ثابتة | نقطة نهاية واحدة، محددة من قبل العميل |
| ** الإفراط في الجلب ** | قد يعود ببيانات أكثر مما هو مطلوب | اطلب بالضبط ما تحتاجه |
| ** نقص الجلب ** | قد تحتاج إلى طلبات متعددة (N+1) | طلب واحد للبيانات المتداخلة |
| التخزين المؤقت | مدمج (التخزين المؤقت لـ HTTP، CDN) | مخصص (ذاكرة تخزين أبولو المؤقتة، الترحيل) |
| الأدوات | الناضجون (الضفيرة، ساعي البريد، المتصفحات) | النمو (GraphiQL، Apollo DevTools) |
| ** منحنى التعلم ** | منخفض | متوسط |
| الإصدار | إصدار URI | أضف الحقول، وتجاهل الحقول القديمة |
| تحميل الملف | أصلي (متعدد الأجزاء) | يتطلب معالجة خاصة |
| ** في الوقت الحقيقي ** | ويب سوكيت، إس إس إي | الاشتراكات |
متى تستخدم GraphQL
- متطلبات البيانات المعقدة والمتداخلة (لوحات المعلومات، تطبيقات الهاتف المحمول).
- تحتاج أنواع العملاء المتعددة (الويب، الهاتف المحمول، إنترنت الأشياء) إلى بيانات مختلفة.
- متطلبات الواجهة الأمامية سريعة التطور.
متى تستخدم الراحة
- عمليات CRUD البسيطة.
- واجهات برمجة التطبيقات العامة ذات قاعدة واسعة من المستهلكين.
- يعد التخزين المؤقت أمرًا مهمًا (CDN لنقاط نهاية GET).
- تحميل الملفات والبيانات الثنائية.
إدارة دورة حياة API
استراتيجية الإصدار
version_policy:
- v1: Initial release (stable, deprecated)
- v2: Current version (active development)
- v3: Planned (future)
deprecation:
notice_period: 6 months
communication: email, API response header
sunset_header: true # Deprecation: true
transition:
new_features: v2 only
bug fixes: v1 critical only
migrations: provide migration guide
رؤوس الإهمال
GET /v1/users/123
Sunset: Sat, 30 Nov 2024 00:00:00 GMT
Deprecation: true
Link: </v2/users/123>; rel="successor-version"
الاستنتاج
يتبع التصميم الجيد لواجهة برمجة التطبيقات هذه المبادئ:
- الاتساق — يجب أن تتبع التسمية وتنسيقات الأخطاء وترقيم الصفحات والمصادقة نفس الأنماط.
- تجربة المطور — وثائق واضحة، وسلوك يمكن التنبؤ به، ورسائل خطأ مفيدة.
- الأمان بشكل افتراضي — HTTPS، والمصادقة، وتحديد المعدل، والتحقق من صحة الإدخال، وCORS.
- التوافق مع الإصدارات السابقة — الإصدار بوعي، والتجاهل بأمان، وإبلاغ التغييرات العاجلة.
- الأداء — ترقيم الصفحات، والتخزين المؤقت للرؤوس، والحقول المتفرقة، والضغط.
واجهة برمجة التطبيقات (API) هي منتج. استثمر في تصميمه، وقم بتوثيقه بدقة، وقم بإصداره بعناية، وتعامل مع كل تغيير جذري بالخطورة التي يستحقها.
مقالات مختارة

50 مهارة من Claude تستحق البناء في 2026

ابن مساعد ملاحظات خاص بالذكاء الاصطناعي
حوّل مجلد ملاحظات Markdown إلى مساعد بحث دون كشف المسودات الخاصة.

أتمتة استخراج بيانات الفواتير باستخدام OCR
ابن خط معالجة يقرأ الفواتير ويستخرج الحقول ويعلّم القيم غير المؤكدة للمراجعة.
التعليقات
0 تعليقاتلا توجد تعليقات معتمدة بعد. قد تنتظر الردود الجديدة المراجعة.