دليل شامل لفهم كل شيء عن الـ APIs مع أمثلة

٢٦ مارس ٢٠٢٦

A Full Guide Understand Everything About APIS With Examples

ملخص

تسمح واجهات برمجة التطبيقات (APIs) للبرامج بالتحدث مع بعضها البعض. يعتبر REST النمط الأكثر شيوعاً (HTTP + JSON)، ولكن GraphQL (لغة استعلام للبيانات)، وWebSockets (للوقت الفعلي)، وgRPC (RPC سريع) تلبي احتياجات مختلفة. تستخدم المصادقة الرموز (Bearer، مفاتيح API) أو OAuth لتفويض المستخدم. تعيد الأخطاء رموز الحالة (2xx للنجاح، 4xx لخطأ العميل، 5xx لخطأ الخادم). أتقن هذه الأنماط وستتمكن من استهلاك أي API بثقة.

تعد الـ API بمثابة عقد: "اتصل بي ببيانات X، وسأعطيك نتيجة Y". بدون واجهات برمجة التطبيقات، سيكون كل شيء معزولاً. بفضلها، يتحدث تطبيقك مع معالجي الدفع، وخدمات الخرائط، ونماذج الذكاء الاصطناعي، وقواعد البيانات. يغطي هذا الدليل النموذج الذهني (ما يحدث بالفعل)، والأنماط الأكثر شيوعاً (REST، GraphQL، WebSocket)، وأمثلة عملية يمكنك تشغيلها اليوم. سواء كنت تدمج خدمة خارجية أو تبني API ليستخدمها الآخرون، فإن فهم هذه الأنماط يجعلك مبرمجاً قوياً.

النموذج الذهني: ما هي الـ API؟

ببساطة: الـ API هي دالة (function) موجودة على خادم شخص آخر تستدعيها عبر الإنترنت.

// Local function (illustrative — never interpolate user input into SQL like this in real code; use parameterized queries)
function getUser(userId) {
  return database.query('SELECT * FROM users WHERE id = ?', [userId]);
}

// API (same idea, but over HTTP)
fetch('https://API.example.com/users/123')
  .then(res => res.json());

الفرق الرئيسي: في الدوال المحلية، تستدعيها مباشرة. أما مع واجهات برمجة التطبيقات، فأنت ترسل طلباً (request) عبر HTTP، ويرسل الخادم رداً (response).

كل طلب API يحتوي على:

  1. Method (أي إجراء: GET، POST، PUT، DELETE)
  2. Endpoint (المسار: /users/123)
  3. Headers (بيانات وصفية: المصادقة، نوع المحتوى)
  4. Body (حمولة بيانات اختيارية)

كل رد API يحتوي على:

  1. Status code (النجاح أو الفشل: 200، 404، 500)
  2. Headers (بيانات وصفية حول الرد)
  3. Body (البيانات الفعلية، عادةً بصيغة JSON)

REST: النمط الأكثر شيوعاً

تعد REST (Representational State Transfer) هي المعيار الصناعي. تستخدم أفعال HTTP لوصف الإجراءات على الموارد (الأسماء).

أساسيات REST

GET    /posts        → Fetch all posts
GET    /posts/123    → Fetch post #123
POST   /posts        → Create a new post
PUT    /posts/123    → Update post #123
DELETE /posts/123    → Delete post #123

لماذا تهم الأفعال والأسماء:

  • GET آمن (لا يغير البيانات)
  • DELETE خطير (يزيل البيانات)
  • POST ينشئ؛ PUT يحدث

مثال REST: جلب البيانات

// Simple GET request
fetch('https://jsonplaceholder.typicode.com/posts/1')
  .then(res => res.json())
  .then(data => console.log(data));

// Output: { id: 1, title: "...", body: "...", userId: 1 }

مثال REST: إنشاء بيانات (POST)

fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    title: 'My Post',
    body: 'This is the content',
    userId: 1
  })
})
  .then(res => res.json())
  .then(data => console.log(data));

// Output: { id: 101, title: "My Post", body: "This is the content", userId: 1 }

مثال REST: تحديث بيانات (PUT)

fetch('https://jsonplaceholder.typicode.com/posts/1', {
  method: 'PUT',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    id: 1,
    title: 'Updated Title',
    body: 'Updated body',
    userId: 1
  })
})
  .then(res => res.json())
  .then(data => console.log(data));

مثال REST: حذف بيانات

fetch('https://jsonplaceholder.typicode.com/posts/1', {
  method: 'DELETE'
})
  .then(res => res.json())
  .then(data => console.log('Deleted:', data));

GraphQL: لغة استعلام لواجهات برمجة التطبيقات

تسمح لك GraphQL بطلب البيانات التي تحتاجها بالضبط—لا أكثر ولا أقل.

REST مقابل GraphQL

REST:

GET /posts/1
→ { id, title, body, userId, createdAt, updatedAt, authorEmail, ... }
(you get everything; wasteful)

GraphQL:

query {
  post(id: 1) {
    title
    body
    author { name email }
  }
}
{ post: { title: "...", body: "...", author: { name: "...", email: "..." } } }
(you get only what you asked for)

مثال GraphQL

const query = `
  query {
    posts {
      id
      title
      author {
        name
      }
    }
  }
`;

fetch('https://API.example.com/graphql', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ query })
})
  .then(res => res.json())
  .then(data => console.log(data.data.posts));

المميزات:

  • لا يوجد جلب زائد للبيانات (تحصل فقط على ما تحتاجه)
  • لا يوجد جلب ناقص للبيانات (لا حاجة لعدة رحلات ذهاب وإياب)
  • كتابة قوية (المخطط يصف ما هو متاح)

العيوب:

  • أكثر تعقيداً في التعلم
  • رفع الملفات قد يكون صعباً
  • تعقيد الاستعلام يمكن أن يثقل كاهل الخوادم

WebSocket: الاتصال في الوقت الفعلي

يحافظ WebSocket على اتصال مفتوح للتحديثات في الوقت الفعلي (الدردشة، الإشعارات، البيانات الحية).

مثال WebSocket

const ws = new WebSocket('wss://API.example.com/live');

ws.addEventListener('open', () => {
  console.log('Connected');
  ws.send(JSON.stringify({ action: 'subscribe', channel: 'prices' }));
});

ws.addEventListener('message', (event) => {
  const data = JSON.parse(event.data);
  console.log('Price update:', data);
});

ws.addEventListener('close', () => {
  console.log('Disconnected');
});

حالات الاستخدام:

  • الدردشة في الوقت الفعلي
  • أسعار الأسهم المباشرة، العملات المشفرة
  • الإشعارات المباشرة
  • أدوات التعاون (مثل Google Docs)

الفرق عن REST:

  • REST تعتمد على طلب-رد (العميل يسأل، الخادم يجيب، ينغلق الاتصال)
  • WebSocket ثنائي الاتجاه (يمكن للعميل والخادم إرسال البيانات في أي وقت)

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

1. مفتاح API

رمز بسيط يتم إرساله مع كل طلب.

fetch('https://API.example.com/data', {
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
})

المميزات: بسيط، يعمل للاتصال بين الخوادم العيوب: إذا تسرب، يمكن لأي شخص استخدامه

2. OAuth 2.0 (تفويض المستخدم)

يقوم المستخدم بتسجيل الدخول في تطبيقك، ويمنح الإذن للوصول إلى بياناته في خدمة أخرى (Gmail، GitHub، Spotify). لا يرى تطبيقك كلمة المرور الخاصة به أبداً.

// User clicks "Sign in with Google"
// Google authenticates user, sends your app a token
// Your app uses that token to fetch user's Google data
fetch('https://www.googleapis.com/calendar/v3/calendars/primary/events', {
  headers: { 'Authorization': `Bearer ${googleToken` }
})

المميزات: يتحكم المستخدم في البيانات التي تصل إليها؛ لا تتعامل أبداً مع كلمات المرور العيوب: إعداد أكثر تعقيداً

3. ملفات تعريف الارتباط للجلسة (Session Cookies)

يقوم الخادم بتعيين ملف تعريف ارتباط؛ ويرسله المتصفح تلقائياً مع كل طلب.

// Login endpoint sets a cookie
fetch('https://API.example.com/login', {
  method: 'POST',
  credentials: 'include', // Send cookies
  body: JSON.stringify({ username, password })
})

// Subsequent requests automatically include the cookie
fetch('https://API.example.com/me', {
  credentials: 'include'
})

المميزات: يعمل بشكل جيد لتطبيقات الويب؛ يتم إرسال ملف تعريف الارتباط تلقائياً العيوب: هجمات CSRF ممكنة؛ أقل ملاءمة لعملاء الهاتف المحمول/واجهات برمجة التطبيقات

رموز حالة HTTP: فهم الردود

الرمزالمعنىمثال
2xxنجاح
200تم (نجح الطلب)GET /posts ← يعيد المنشورات
201تم الإنشاء (تم إنشاء مورد جديد)POST /posts ← ينشئ منشوراً
204لا يوجد محتوى (نجاح، لم يتم إرجاع بيانات)DELETE /posts/1
3xxإعادة توجيه
301تم النقل بشكل دائمرابط قديم ← رابط جديد
304لم يتم التعديل (الرد المخزن مؤقتاً سليم)رأس If-Modified-Since
4xxخطأ عميل
400طلب سيئ (طلب غير صحيح)حقل مطلوب مفقود
401غير مصرح به (المصادقة مطلوبة)نسيت مفتاح API
403ممنوع (ليس لديك إذن)غير المسؤول يحاول الوصول لمسار المسؤول
404غير موجود (المورد غير موجود)GET /posts/999
429طلبات كثيرة جداً (تجاوز الحد)قمت بطلبات كثيرة بسرعة كبيرة
5xxخطأ خادم
500خطأ خادم داخلي (حدث عطل ما)خطأ في كود الخادم
503الخدمة غير متوفرة (متوقفة مؤقتاً)صيانة أو ضغط زائد

القاعدة الذهبية: إذا كانت الحالة 2xx، فقد نجح الطلب. إذا كانت 4xx أو 5xx، فهناك خطأ ما.

معالجة الأخطاء: عندما تسوء الأمور

async function fetchData(url) {
  try {
    const res = await fetch(url);

    if (!res.ok) {
      throw new Error(`HTTP ${res.status: ${res.statusText`);
    }

    return await res.json();
  } catch (err) {
    console.error('API error:', err.message);
    // Handle gracefully: show user message, retry, etc.
  }
}

سيناريوهات شائعة:

  • خطأ في الشبكة: لا يمكن الوصول إلى الخادم (انتهاء الوقت، لا يوجد إنترنت). يساعد منطق إعادة المحاولة هنا.
  • خطأ 4xx: طلب سيئ من جانبك (قم بتصحيح الطلب).
  • خطأ 5xx: الخادم معطل (أعد المحاولة أو صعد المشكلة).
  • تحديد المعدل (429): طلبات كثيرة جداً. انتظر قبل إعادة المحاولة.

تحديد المعدل: كن لطيفاً

غالباً ما تضع واجهات برمجة التطبيقات حداً للطلبات لمنع إساءة الاستخدام.

// Check headers for rate limit info
const remaining = res.headers.get('X-RateLimit-Remaining');
const resetTime = res.headers.get('X-RateLimit-Reset');

if (remaining === '0') {
  console.log(`Rate limited. Reset at ${new Date(resetTime * 1000)`);
}

أفضل الممارسات: تحقق من الحصة المتبقية قبل كل طلب؛ وتراجع بلباقة عند الوصول للحد.

مثال واقعي: بناء أداة للبحث عن مستخدمي GitHub

async function getGitHubUser(username) {
  const url = `https://API.GitHub.com/users/${username}`;

  try {
    const res = await fetch(url);

    if (res.status === 404) {
      throw new Error('User not found');
    }

    if (!res.ok) {
      throw new Error(`HTTP ${res.status}`);
    }

    const user = await res.json();
    console.log(`${user.name} has ${user.public_repos} repos`);

  } catch (err) {
    console.error('Error:', err.message);
  }
}

getGitHubUser('torvalds'); // Linus Torvalds

الخلاصة

تعد الـ APIs هي الطريقة التي تتواصل بها البرمجيات الحديثة. يهيمن REST لبساطته؛ ويتفوق GraphQL في المرونة؛ بينما يتيح WebSocket التواصل في الوقت الفعلي. تختلف طرق المصادقة حسب حالة الاستخدام (مفاتيح API، OAuth، ملفات تعريف الارتباط "cookies"). تخبرك أكواد الحالة بالنجاح أو الفشل؛ والتعامل مع الأخطاء يجعل تطبيقك مرنًا. مع إتقان هذه الأنماط، يمكنك دمج أي خدمة خارجية، وبناء APIs يستهلكها الآخرون، واستكشاف مشكلات الشبكة وإصلاحها بثقة. ابدأ بـ REST API بسيط (مثل JSONPlaceholder)، ثم انتقل إلى خدمات حقيقية (GitHub، Stripe، OpenAI) عندما تصبح أكثر تمكنًا.


نشرة أسبوعية مجانية

ابقَ على مسار النيرد

بريد واحد أسبوعياً — دورات، مقالات معمّقة، أدوات، وتجارب ذكاء اصطناعي.

بدون إزعاج. إلغاء الاشتراك في أي وقت.