مقال

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

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

واجهة برمجة التطبيقات (API) (واجهة برمجة التطبيقات) هي عقد بين مزود الخدمة وعملائه. تعتبر واجهة برمجة التطبيقات (API) المصممة جيدًا بديهية ومتسقة وسهلة الاستخدام. تؤدي واجهة برمجة التطبيقات (API) سيئة التصميم إلى إحباط المطورين وزيادة عبء الدعم ونقاط الضعف الأمنية والتغييرات الباهظة التكلفة.

3 دقيقة قراءةاللغة: AR العربيةمجاني0 تصفيقات0 تعليقات
التقنيةمقالات هندسيةأدلة المنصةDesignPracticesWeb DevelopmentTechnologyEngineering ArticlesPlatform Guides
خيارات القراءة

مقدمة

واجهة برمجة التطبيقات (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"

الاستنتاج

يتبع التصميم الجيد لواجهة برمجة التطبيقات هذه المبادئ:

  1. الاتساق — يجب أن تتبع التسمية وتنسيقات الأخطاء وترقيم الصفحات والمصادقة نفس الأنماط.
  2. تجربة المطور — وثائق واضحة، وسلوك يمكن التنبؤ به، ورسائل خطأ مفيدة.
  3. الأمان بشكل افتراضي — HTTPS، والمصادقة، وتحديد المعدل، والتحقق من صحة الإدخال، وCORS.
  4. التوافق مع الإصدارات السابقة — الإصدار بوعي، والتجاهل بأمان، وإبلاغ التغييرات العاجلة.
  5. الأداء — ترقيم الصفحات، والتخزين المؤقت للرؤوس، والحقول المتفرقة، والضغط.

واجهة برمجة التطبيقات (API) هي منتج. استثمر في تصميمه، وقم بتوثيقه بدقة، وقم بإصداره بعناية، وتعامل مع كل تغيير جذري بالخطورة التي يستحقها.

مقالات مختارة

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

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

التقنيةAIAi GuidesAI Agents
0 تصفيقات
قراءة
ابن مساعد ملاحظات خاص بالذكاء الاصطناعي
مميزAR
9 دمجاني

ابن مساعد ملاحظات خاص بالذكاء الاصطناعي

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

التقنيةأدلة المنصةالكتابة بالذكاء الاصطناعيAIAutomationData
0 تصفيقات
قراءة
أتمتة استخراج بيانات الفواتير باستخدام OCR
تحريريAR
8 دمجاني

أتمتة استخراج بيانات الفواتير باستخدام OCR

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

التقنيةمقالات هندسيةالكتابة بالذكاء الاصطناعيAIAutomationData
0 تصفيقات
قراءة

التعليقات

0 تعليقات

لا توجد تعليقات معتمدة بعد. قد تنتظر الردود الجديدة المراجعة.