كيف يعرف تطبيق الطقس على هاتفك درجة الحرارة في مدينتك الآن؟ وكيف يعرض موقع حجز طيرانٍ أسعارًا حيّةً من عشرات الشركات في ثوانٍ؟ الجواب كلمةٌ تحكم العالم الرقميّ: «واجهة برمجة التطبيقات» (API). حتى الآن بنيتَ موقعًا يعمل كـ«جزيرةٍ» مستقلّة بـHTML وCSS وجافاسكربت. لكنّ قوّة الويب الحديث ليست في الجزر المعزولة، بل في «الجسور» التي تربطها، والـAPI هي لغة بناء هذه الجسور. سأفكّكها هنا بتشبيهٍ بسيط، ثمّ أريك بشيفرةٍ حقيقيةٍ كيف تجلب بها بياناتٍ حيّةً من خادمٍ بعيدٍ إلى صفحتك.
ما الـ API؟ تشبيه النادل في المطعم
أبسط طريقةٍ لفهم الـAPI أن تتخيّلها «نادلًا في مطعم». أنت العميل الجالس على الطاولة، وكلّ ما تراه وتتفاعل معه هو واجهة المستخدم الجميلة: القائمة الأنيقة، والديكور، والإضاءة (هذه هي الواجهة الأمامية). أمّا المطبخ فهو «الصندوق الأسود» المعقّد المغلق: المكوّنات الخام (قاعدة البيانات)، والوصفات السرّية (منطق العمل)، والطهاة والمعدّات (الخوادم). هذه هي الواجهة الخلفية.
تخيّل مطعمًا بلا نادل. ستقع مشكلتان. الأولى الفوضى: لا تستطيع اقتحام المطبخ، فأنت لا تتكلّم «لغته» ولا تعرف أين المكوّنات وكيف تعمل الأفران؛ لو دخلت وصرخت «أريد طعامًا» لعطّلت العمل ولم يفهمك أحد. والثانية الأمان: المطبخ مكانٌ خطير، لا يصحّ أن يتجوّل العملاء بين السكاكين والنيران (وهذا تأمين قاعدة البيانات والخادم من الوصول المباشر). النادل يحلّ المشكلتين معًا: واجهةٌ منظّمةٌ آمنةٌ تجعل العملية ممكنة.
وعمل النادل أربع خطوات. أوّلًا يقدّم لك «القائمة»، وهي «توثيق الـAPI»: العقد الذي يخبرك بما تستطيع طلبه (الوظائف المتاحة، أو «نقاط النهاية» Endpoints) وبالتنسيق الدقيق لطلبه (المعطيات Parameters). لا تطلب بيتزا من مطعم ستيك ليست في قائمته. وثانيًا يأخذ طلبك المبنيّ على قواعد القائمة («شريحة لحمٍ متوسطة النضج مع بطاطس»)، وهو في التقنية طلب HTTP. وثالثًا يترجمه للمطبخ بلغته الفنية، فيستدعي الـAPI على الخادم سلسلةً من الإجراءات (يسأل قاعدة البيانات، يحسب السعر، يأمر البرنامج الخلفيّ) دون أن ترى أنت شيئًا من هذا التعقيد. ورابعًا يعود بالنتيجة: لا يحضر لك الطاهي المكوّنات الخام في أكياس، بل يقدّم النادل الطبق الجاهز منظّمًا، وهي «استجابة HTTP»: لا يرسل الخادم قاعدة بياناته كلّها، بل ما طلبته فقط، بتنسيقٍ نظيفٍ موحّد.
الـAPI إذن وسيطٌ يتيح لتطبيقين (الأماميّ والخلفيّ) أن يتحادثا بلغةٍ موحّدةٍ منظّمة، دون أن يحتاج أحدهما إلى معرفة تفاصيل عمل الآخر. وهنا يقف التشبيه: النادل بشرٌ يفهم النيّة، أمّا الـAPI فيتطلّب طلبًا دقيقًا بالصيغة المحدّدة حرفًا حرفًا، فهو يمنحك «طبقة تجريدٍ» تضمن الأمان والكفاءة لا لطفًا إنسانيًّا.
لغة الـ API: HTTP وJSON
هذه المحادثة المنظّمة ليست سحرًا، بل تتبع البروتوكولات التي مرّت بك. وتنقسم لغتها قسمين: قناة الاتّصال (كيف يجري الطلب والردّ)، ولغة البيانات (تنسيق ما يُتبادَل).
قناة الاتّصال: بروتوكول HTTP
الـAPI ليست شيئًا ماديًّا، بل مجموعة «نقاط نهايةٍ» تعيش على خادمٍ بعيد. ونقطة النهاية ببساطة عنوان URL محدّدٌ يستمع لطلباتٍ معيّنة؛ فحين «تستدعي» واجهةً، أنت ترسل طلب HTTP إلى عنوانٍ بعينه. والتوثيق يخبرك أيّ «أفعالٍ» (طرق HTTP) تستعملها لكل «طبقٍ» (نقطة نهاية)، ولكلّ فعلٍ نيّةٌ محدّدة:[1]
- GET (اقرأ): «أحضِر لي معلوماتٍ موجودة». مثل
GET /api/weather?city=Damascus، حيث/api/weatherنقطة النهاية و?city=Damascusسلسلة الاستعلام التي مرّت بك في مقال URL. - POST (أنشئ): لا تطلب شيئًا بل «تقدّم» معلوماتٍ جديدة، تُرسَل في «جسم الطلب» لا في الرابط، كأنك تملأ استمارةً وتسلّمها. هنا تُرسَل البيانات الحسّاسة.
- PUT وPATCH (عدّل): لتحديث معلوماتٍ موجودة.
- DELETE (احذف): لإلغاء مورد.
والمحادثة ليست طلباتٍ فقط؛ يردّ النادل بـ«رموز حالةٍ» احترافيةٍ توضّح النتيجة:[2] 200 OK («تفضّل، هذا طلبك»)، و201 Created («سُجّلت استمارتك» بعد POST)، و404 Not Found («لا طبق بهذا الاسم» نقطة نهايةٍ غير موجودة)، و401 Unauthorized («لم تُثبت هويّتك» تحتاج مفتاحًا)، و429 Too Many Requests («تجاوزتَ حدّ الطلبات المسموح لك»)، و500 Internal Server Error («وقع حادثٌ في المطبخ» خطأٌ في الخادم).
لغة البيانات: تنسيق JSON
ردّ النادل بـ200 OK، فكيف يقدّم لك «الطبق»؟ الخوادم لا ترسل لغةً بشريةً ولا صفحات HTML منسّقة، لأن الواجهة الأمامية قد تكون تطبيق هاتفٍ أو ساعةً ذكيّةً لا موقع ويب. فتستعمل تنسيقًا نصّيًّا منظّمًا خفيفًا يسهل على الآلات قراءته: «JSON» (JavaScript Object Notation).[3] وكما يوحي اسمه، فهو حرفيًّا «كائن» جافاسكربت، المفهوم نفسه الذي مرّ بك، فيسهل على شيفرتك التعامل معه. فبدل طبقٍ مزخرف، يسلّمك النادل «بطاقة ملاحظاتٍ» منظّمة:
{
"city": "Damascus",
"temperature": 25,
"condition": "Clear",
"unit": "Celsius"
}
تستلم شيفرتك هذا الكائن، وتقرأ منه ما تريد (مثل data.temperature)، ثمّ تستعمل معرفتها بالـDOM لتعرضه جميلًا على الصفحة.
مثال عمليّ: جلب بياناتٍ حيّة بجافاسكربت
تعلّمتَ سابقًا أن تتفاعل بجافاسكربت مع عناصر صفحتك (كزرّ الوضع الليليّ). الآن ترتقي خطوةً: تجعل صفحتك تتحدّث مع العالم الخارجيّ، فتجلب بياناتٍ حيّةً من خادمٍ آخر وتعرضها. المهمّة: جلب «حقيقةٍ عشوائيةٍ عن القطط» من واجهةٍ عامّةٍ مجّانية. أوّلًا تهيّئ «المكان» في HTML: فقرةٌ بمعرّفٍ فريدٍ تنتظر البيانات.
<h2>حقيقة عشوائية عن القطط:</h2>
<p id="fact-text">يتم الآن تحميل حقيقة جديدة...</p>
ثمّ تكتب المنطق في script.js مستعملًا أداة جافاسكربت الحديثة المدمجة لإجراء طلبات HTTP واسمها «fetch» (وهي «المكالمة الهاتفية» التي تجريها جافاسكربت للنادل).[4] وتستعمل صيغة async/await الحديثة التي تجعل الشيفرة تُقرأ كأنها تجري خطوةً خطوة:
document.addEventListener('DOMContentLoaded', function() {
// 1. عنوان النادل (نقطة نهاية الـAPI)
const apiUrl = 'https://catfact.ninja/fact';
// async تخبر جافاسكربت أن هذه الدالّة ستنتظر بياناتٍ من الخارج
async function getCatFact() {
// 2. المكالمة: إرسال طلب GET، وawait يوقف التنفيذ حتى يردّ النادل
const response = await fetch(apiUrl);
// 3. فكّ التغليف: تحويل الردّ من JSON إلى كائن جافاسكربت
const data = await response.json();
// 4. تحديث الصفحة بمهارات الـDOM التي تعلّمتها
const factElement = document.querySelector('#fact-text');
factElement.textContent = data.fact;
}
getCatFact();
});
تأمّل كيف اجتمع كلّ ما تعلّمته في هذه الأسطر. سطر await fetch هو التطبيق العمليّ لمقال HTTP: أرسل متصفّحك طلب GET كاملًا إلى الخادم. وسطر response.json() فكّ تنسيق JSON وحوّله كائنًا تستعمله. وسطر querySelector هو تطبيق مقال جافاسكربت: وجدتَ عنصرًا في شجرة الـDOM وغيّرتَ محتواه. بهذه الخطوات نفّذتَ المفهوم الذي تقوم عليه كلّ تطبيقات الويب الحديثة: فصلتَ الواجهة (HTML/CSS) عن البيانات (API). هكذا يعمل فيسبوك وتويتر: الواجهة هيكلٌ فارغ، وجافاسكربت تجلب باستمرارٍ بياناتٍ جديدةً (منشورات، تعليقات) وتعرضها لحظيًّا.
لكنّ المثال أعلاه ناقصٌ في أمرٍ مهمّ: ماذا لو فشل الطلب؟ قد ينقطع الإنترنت، أو يردّ الخادم بخطأ، أو تكون نقطة النهاية خاطئة. الشيفرة الحقيقية لا تفترض النجاح دائمًا، بل تتحوّط للفشل بـtry/catch وبفحص نجاح الردّ:
async function getCatFact() {
try {
const response = await fetch(apiUrl);
if (!response.ok) { // 404 أو 500 مثلًا
throw new Error('خطأ في الخادم: ' + response.status);
}
const data = await response.json();
factElement.textContent = data.fact;
} catch (error) {
factElement.textContent = 'تعذّر جلب الحقيقة، حاول لاحقًا.';
}
}
انتبه إلى تفصيلٍ يخدع المبتدئ: fetch لا يعدّ خطأ 404 أو 500 «فشلًا» تلقائيًّا (لأنه نجح في الوصول إلى الخادم وتلقّى ردًّا)، فلا يقفز إلى catch. لذلك تفحص response.ok بنفسك. التعامل مع الفشل بلطفٍ (رسالةٌ واضحةٌ للمستخدم بدل صفحةٍ مكسورة) هو ما يفرّق التطبيق الاحترافيّ عن النموذج التعليميّ.
لماذا تفشل بعض الطلبات؟ المصادقة ومفاتيح API
نجح المثال مع catfact.ninja بسهولة. لكن لو جرّبت الشيفرة نفسها مع واجهة تويتر أو خرائط جوجل، لفشل طلبك فورًا بخطأ 401 Unauthorized. السبب «المصادقة». فواجهة حقائق القطط أشبه بـ«كشك عيّناتٍ مجّانيةٍ» في الشارع، هدفه التوزيع للجميع بلا قيد. أمّا الواجهات الاحترافية فأشبه بـ«نادٍ خاصٍّ حصريّ»: لا يقبل النادل طلبك حتى تثبت أنك عضوٌ يحقّ له الدخول.
ولماذا تشترط المصادقة؟ لثلاثة أسباب. الأمان: يجب أن تتأكّد الواجهة أنك «أنت» قبل أن تسمح بنشر تغريدةٍ باسمك أو قراءة رسائلك. والمحاسبة: كثيرٌ من الواجهات منتجاتٌ مدفوعة (كخرائط جوجل أو واجهة OpenAI)، فتحتاج معرفة من يطلب لتحسب استهلاكه. والتنظيم: لمنع سوء الاستعمال وهجمات الإغراق، تفرض «حدًّا أقصى للطلبات» (Rate Limit)، كألف طلبٍ في الساعة لكل عضو، فلا ينهار الخادم بطلبات عضوٍ واحدٍ على حساب البقيّة.
والحلّ «مفتاح الـAPI» (API Key): بطاقة عضويةٍ فريدةٌ تعطيك إيّاها الخدمة حين تشترك، سلسلةٌ طويلةٌ من الأحرف والأرقام تعمل ككلمة مرورٍ لتطبيقك. ولا تُرسَل في الرابط، بل بأمانٍ داخل «ترويسات الطلب» كما مرّ بك في مقال HTTP (تسلّمها للنادل بهدوءٍ لا تصرخ بها عبر الغرفة):
const apiKey = 'YOUR_SECRET_API_KEY';
const apiUrl = 'https://api.example.com/data';
const response = await fetch(apiUrl, {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const data = await response.json();
فحين يستلم النادل طلبك، يفحص الترويسات، ويرى بطاقتك (Authorization)، ويتحقّق من صلاحيتها، ثمّ يقرّر أيخدمك أم يردّ بـ401. ولهذا، قبل أن «تستدعي النادل» في أيّ خدمةٍ احترافية، اذهب أوّلًا إلى «مكتب الاستقبال» (موقع المطوّرين الخاصّ بالخدمة)، وسجّل، واحصل على مفتاحك. وتنبيهٌ مهمّ: لا تضع مفتاحك السرّيّ في شيفرة الواجهة الأمامية التي يراها أيّ زائر، بل في الخادم؛ فالمفتاح المكشوف يُسرَق ويُستعمَل على حسابك.
ما REST؟ دليل الأسلوب الموحّد
ستصادف مصطلح «REST» أو «RESTful API» في كل مكان. تخيّل لو أن كل مطعمٍ في العالم له طريقته الخاصّة في أخذ الطلب: واحدٌ يطلب أن «تصرخ» بطلبك ببروتوكولٍ معقّد، وآخر أن «تكتبه على منديلٍ» بتنسيقٍ غريب، وثالثٌ بأوامره الخاصّة. لاضطُررت كمطوّرٍ إلى تعلّم «لغةٍ» جديدةٍ لكل خدمة، وهذا كابوسٌ من عدم الكفاءة.
«REST» (Representational State Transfer) ليس تقنيةً ولا لغة، بل «دليل أسلوبٍ» ومجموعة مبادئ معماريةٍ اقترحها روي فيلدنغ سنة 2000.[5] هو كـ«دليل التدريب الموحّد» لسلسلة مطاعم عالمية: يضمن أن النادل في نيويورك يتصرّف تمامًا كالنادل في طوكيو. فبمجرّد أن تتعلّم الطلب من مطعمٍ واحدٍ يتبع الأسلوب، تعرف كيف تطلب من تسعين في المئة من الواجهات الحديثة. وجماله أنه لا يخترع جديدًا، بل يستعمل تقنيات HTTP بالطريقة التي صُمّمت لها، عبر ثلاثة مبادئ.
الأوّل التركيز على «الموارد» (الأسماء لا الأفعال): بدل عشرات الأوامر، لديك موردٌ واحدٌ اسمه users تتفاعل معه بأفعال HTTP القياسية. فبدل POST /getUser وPOST /createUser وPOST /deleteUser الفوضوية، تكتب:
GET /api/users # أحضِر كل المستخدمين
GET /api/users/123 # أحضِر المستخدم 123 فقط
POST /api/users # أنشئ مستخدمًا جديدًا
PUT /api/users/123 # حدّث المستخدم 123
DELETE /api/users/123 # احذف المستخدم 123
والثاني أنه «عديم الحالة»: كل طلبٍ مستقلٌّ بذاته، والخادم لا يتذكّرك، فترسل بطاقتك (المفتاح) مع كلّ طلب. والثالث استعمال تنسيقاتٍ موحّدةٍ للبيانات، وأشيعها JSON. وحين يعيد موردٌ قائمةً ضخمةً (آلاف المستخدمين مثلًا)، لا يرسلها الخادم دفعةً واحدةً تُثقل الشبكة، بل «صفحةً صفحة» (Pagination): تطلب الصفحة الأولى، ثمّ الثانية، عبر معطياتٍ مثل ?page=2&limit=20. وهذا ما تراه في كل موقعٍ يعرض نتائج على صفحات. فحين تسمع أن واجهةً «RESTful»، فالمقصود ببساطةٍ أنها تتبع هذا الأسلوب المنطقيّ المتوقّع، وهو الفلسفة التي تحكم تقريبًا كل الواجهات الحديثة التي ستتعامل معها.
أمورٌ ستصادفها مع الـ API
وقبل الختام، ستّة أمورٍ ستلتقيها حتمًا في طريقك. الأوّل، وأكثرها إرباكًا للمبتدئ، خطأ «CORS»: حين تحاول جلب بياناتٍ من نطاقٍ مختلفٍ عن نطاق صفحتك، يرفض المتصفّح أحيانًا الطلب حمايةً لك، ما لم يأذن الخادم البعيد صراحةً للنطاقات الأخرى. ليس هذا عطلًا في شيفرتك، بل سياسة أمانٍ في المتصفّح، وحلّه يكون من جهة الخادم لا المتصفّح، فلا تُضِع وقتك تبحث في شيفرتك.
والثاني «Webhooks» (الخطّافات)، وهي عكس ما تعلّمته: بدل أن تسأل أنت الخادم باستمرارٍ «هل من جديد؟»، يتّصل بك الخادم هو حين يقع الحدث، فيرسل البيانات إلى عنوانٍ تحدّده له. هكذا يخبرك نظام الدفع أن عمليةً نجحت لحظة نجاحها، دون أن تستنزف مواردك بالسؤال المتكرّر. والثالث «GraphQL»، بديلٌ حديثٌ لـREST طوّرته فيسبوك، يتيح للعميل أن يطلب بالضبط الحقول التي يريدها في طلبٍ واحد، فيتجنّب جلب بياناتٍ زائدةٍ أو نقص بيانات؛ لا يحلّ محلّ REST بل يزاحمه في المشاريع الكبيرة.
والرابع «OpenAPI» (المعروف سابقًا بـ«Swagger»): حين تفتح توثيق واجهةٍ احترافية، فغالبًا لا تجد صفحةً كتبها إنسانٌ بيده، بل «قائمةً» مكتوبةً بصيغةٍ قياسيةٍ تقرؤها الآلة، تصف كلّ نقطة نهايةٍ ومعطياتها وشكل ردّها بدقّة. هذه الصيغة اسمها OpenAPI، معيارٌ مفتوحٌ ترعاه مؤسّسة OpenAPI Initiative.[6] وفائدتها مضاعفة: أداةٌ مثل Swagger UI تحوّل هذا الملفّ إلى توثيقٍ تفاعليٍّ تجرّب فيه الطلبات من متصفّحك مباشرةً، وأدواتٌ أخرى تولّد منه شيفرة العميل تلقائيًّا بلغتك فتوفّر عليك كتابتها يدويًّا. وكبرى الخدمات مثل Stripe وGitHub تنشر وصف واجهتها بهذه الصيغة، فتنمو حولها منظومةٌ من الأدوات الجاهزة. فحين ترى زرّ «Try it out» في توثيق واجهةٍ، فأنت أمام قائمةٍ حيّةٍ بُنيت على هذا المعيار.
والخامس «إصدارات الواجهة» (Versioning): الواجهة عقدٌ تعتمد عليه آلاف التطبيقات، فلا يصحّ أن يتغيّر فجأةً فيكسرها كلّها دفعةً واحدة. لذلك تُصدر الخدمات نسخًا مرقّمةً من واجهتها تراها في المسار نفسه، مثل /v1/users ثمّ /v2/users، فتبقى النسخة القديمة تعمل بينما تنتقل أنت إلى الجديدة على مهلك دون أن ينكسر تطبيقك بين ليلةٍ وضحاها. ولهذا، حين تقرأ توثيق واجهةٍ، انتبه إلى رقم إصدارها، فما يصحّ في v1 قد يتغيّر في v2.
والسادس أن كثيرًا من قوّتك كمطوّرٍ ستأتي من واجهاتٍ جاهزةٍ يبنيها غيرك. بدل أن تبني خريطةً من الصفر تستعمل واجهة خرائط جوجل، وبدل أن تكتب نظام دفعٍ تستعمل واجهة شركةٍ مثل Stripe، وبدل أن تبني نظام تسجيل دخولٍ تستعمل «الدخول بحساب جوجل»، وتضيف ذكاءً اصطناعيًّا عبر واجهة OpenAI. التطبيق الحديث في جوهره تركيبٌ بارعٌ لواجهاتٍ متعدّدة، تجمعها أنت لتبني شيئًا جديدًا. ومن هنا يصير إتقان «استهلاك» الواجهات مهارةً لا تقلّ أهمّيةً عن كتابة الشيفرة نفسها. وأفضل ما تبدأ به أن تجرّب: ابحث عن واجهاتٍ عامّةٍ مجّانية (توجد قوائم منظّمةٌ بالمئات منها)، واختر واحدةً تهمّك، واقرأ توثيقها، واجلب منها بياناتٍ كما فعلتَ هنا. ساعةٌ واحدةٌ من اللعب بواجهةٍ حقيقيةٍ تعلّمك أكثر من فصلٍ كاملٍ من القراءة.
من استهلاك الجسور إلى بنائها
فككتَ واحدًا من أهمّ مفاهيم الويب الحديث: بدأتَ بتشبيه النادل لتفهم فلسفة الـAPI، ثمّ لغتها (HTTP وJSON)، ثمّ جلبتَ بياناتٍ حيّةً بأسطرٍ قليلةٍ من جافاسكربت، وعرفتَ لماذا تحتاج مفاتيح المصادقة، وما «دليل الأسلوب» REST. الـAPI هي الجسور التي تحوّل الويب من جزرٍ معزولةٍ إلى نظامٍ مترابط، وإتقانها نقلتك من مطوّرٍ يبني مواقع ثابتةٍ إلى مطوّرٍ يبني تطبيقاتٍ حيّةً متّصلةً بالعالم.
وكلّ ما فعلتَه هنا «استهلاكٌ» لواجهةٍ بناها غيرك. لكنّ للقصّة وجهًا آخر: أن تبني واجهتك أنت. حين تتعلّم الواجهة الخلفية، ستكتب «النادل» بنفسك، فتعرّف نقاط نهايةٍ تستمع للطلبات، وتصلها بقاعدة بيانات، وتعيد JSON. ولأن جافاسكربت تعمل على الخادم عبر Node.js (كما مرّ بك)، يكتب كثيرٌ من مطوّري الواجهات الأمامية واجهاتهم الخلفية بأداةٍ مثل Express باللغة نفسها. حينها تكون قد جلست على طرفَي الطاولة: عميلًا يطلب، ونادلًا يخدم.
وحين تكبر هذه التطبيقات وتزداد بياناتها وتفاعلها، تصير إدارتها بجافاسكربت الخالصة وحدها أمرًا شاقًّا، فيلجأ المطوّرون إلى منظومةٍ حديثةٍ من الأدوات تنظّم التعقيد وتربط القطع بعضها ببعض. لكن قبل الأطر التي تُبنى على هذه المنظومة، لا بدّ أن تفهم المنظومة نفسها: مدير الحزم، والمُجمِّع، وخطوة البناء. وهذا موضوع المقال التالي: «أدوات البناء الحديثة: npm وVite وخطوة البناء».
المصادر
- MDN: طرق HTTP. أفعال الطلب GET وPOST وPUT وDELETE ودلالاتها.
- MDN: رموز حالة HTTP. معاني 200 و201 و401 و404 و500.
- MDN: العمل مع JSON. تنسيق البيانات النصّيّ المبنيّ على كائن جافاسكربت.
- MDN: استعمال Fetch API. جلب البيانات من خادمٍ بجافاسكربت.
- Roy Fielding: النمط المعماريّ REST (أطروحته، 2000). المبادئ التي وحّدت بناء واجهات الويب.
- OpenAPI Initiative: مواصفة OpenAPI. المعيار المفتوح لوصف واجهات REST (المعروف سابقًا بـSwagger) والأدوات المبنيّة عليه.