Kodokon kodokon.com

أول خادم HTTP أصلي لك

تنشئ خادم ويب باستخدام الوحدة http الخاصة بـ Node، وتستجيب للطلبات، وتُرجِع JSON.

10 دقيقة · 3 أسئلة

افتح هذا الدرس في Kodokon

إن خادم الويب برنامج يعمل باستمرار وينتظر الطلبات (requests): وهي طلبات يرسلها عميل (متصفح، أو تطبيق جوّال، وما إلى ذلك). ولكل طلب، يُرجِع استجابة (response). يتبع هذا الحوار بروتوكول HTTP، اللغة المشتركة للويب. تتضمّن Node وحدة http جاهزة للاستخدام: لا شيء لتثبيته. مفهوم أخير: المنفذ (port)، وهو رقم يحدّد برنامجًا معيّنًا على جهاز، مثل رقم شقة في مبنى. سنستخدم المنفذ 3000؛ أما localhost فيشير ببساطة إلى جهازك أنت.

JAVASCRIPT
import http from "node:http";

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader("Content-Type", "text/plain");
  res.end("Hello from my server!");
});

server.listen(3000, () => {
  console.log("Server at http://localhost:3000");
});
احفظ هذا الكود في server.js ثم نفّذ node server.js.

لنحلّله. تتلقّى http.createServer دالة تُستدعى عند كل طلب، بوسيطين: req (الطلب الوارد) وres (الاستجابة قيد الإنشاء). يضبط res.statusCode = 200 رمز الحالة (status code) - يعني 200 "كل شيء على ما يرام". تضيف res.setHeader ترويسة (header)، وهي بيانات وصفية عن الاستجابة: هنا تنسيقها، نص عادي. ترسل res.end الاستجابة وتغلقها. وأخيرًا، تضع server.listen(3000) الخادم في وضع الإنصات على المنفذ 3000. افتح http://localhost:3000 في متصفحك: يظهر نصك. لاحظ أن البرنامج لا يعيد لك التحكم: بل ينتظر الطلبات. أوقفه بـ Ctrl+C.

نادرًا ما تُرجِع الخوادم الحديثة نصًا عاديًا: بل تكشف واجهات برمجية (APIs) تستجيب بتنسيق JSON، ذلك التنسيق النصي الذي تعرفه بالفعل، والذي تفهمه كل لغة. تعديلان: تصبح ترويسة Content-Type هي application/json، ويُحوَّل كائن JavaScript إلى نص باستخدام JSON.stringify. لنغتنم الفرصة لنتفاعل بشكل مختلف تبعًا لـ req.url، وهو المسار الذي طلبه العميل: هذا هو أساس التوجيه (routing).

JAVASCRIPT
import http from "node:http";

const server = http.createServer((req, res) => {
  res.setHeader("Content-Type", "application/json");

  if (req.url === "/api/message") {
    const body = { message: "Hello!", ok: true };
    res.statusCode = 200;
    res.end(JSON.stringify(body));
    return;
  }

  res.statusCode = 404;
  res.end(JSON.stringify({ error: "Not found" }));
});

server.listen(3000, () => {
  console.log("http://localhost:3000/api/message");
});
يستجيب مسار معروف بالرمز 200 مع كائن JSON؛ ويتلقّى أي مسار آخر الرمز 404.

يعني رمز الحالة 404 "غير موجود": فالمسار المطلوب لا يطابق أي مسار معروف. لاحظ return بعد الاستجابة الأولى: فهو يمنع الكود من الاستمرار وإرسال استجابة ثانية، ما قد يُسبّب خطأً. للاختبار، افتح العنوان في المتصفح، أو استخدم curl، وهي أداة سطر أوامر ترسل طلبات HTTP وتعرض الاستجابة في الطرفية.

BASH
curl http://localhost:3000/api/message
في طرفية ثانية، أثناء تشغيل الخادم: تظهر استجابة JSON.

اختبار المعرفة

تأكّد من أنك تذكّرت النقاط الأساسية في هذا الدرس.

  1. ماذا تفعل server.listen(3000)؟
    • تضع الخادم في وضع الإنصات للطلبات على المنفذ 3000
    • ترسل طلبًا إلى المنفذ 3000
    • تحدّ الخادم بـ 3000 طلب متزامن
    • تفتح المتصفح على localhost:3000
  2. أيّ ترويسة ترسلها للإشارة إلى أن الاستجابة بتنسيق JSON؟
    • Accept: application/json
    • Content-Type: application/json
    • Format: json
  3. لماذا نمرّر الكائن عبر JSON.stringify قبل res.end؟
    • لضغط الاستجابة وتوفير الوقت
    • للتحقق من أن الكائن لا يحتوي على أي خطأ
    • لأن استجابة HTTP تحمل نصًا، لا كائن JavaScript