3.1 · إكسبريس (Express) : الطرق والوسائط والطلبات والردود

المستوى 3 · إكسبريس وقواعد البيانات (Express & databases)

3.1إكسبريس (Express) : الطرق والوسائط والطلبات والردود

الهدف: بناء تطبيق/API مع إكسبريس (Express) : التوجيه (routing) (بما فيه الطرق الديناميكية)، و req/res المُثراة، والوسائط (middlewares) — قلب تطوير وب Node.
الوقت المقدّر: 12 دقيقة · قراءة ذاتية · إذا كان لديك 5 دقائق فقط: اقرأ «الأساسي في 30 ثانية» + المخطط.

الأساسي في 30 ثانية

  • إكسبريس (Express) يُحسّن الوحدة http : توجيه نظيف (app.get/post/put/delete)، ومعاملات ديناميكية (/users/:id ← req.params.id)، وردود بسطر واحد (res.json).
  • الوسيط (middleware) هو المفهوم المفتاح : دالة (req, res, next) يعبرها كل طلب ؛ تتصرف ثم تنادي next() أو ترد لوقف السلسلة.
  • ترتيب الخط مهم : المحلل أولا (express.json())، ثم التحقق والمصادقة، والرد أخيرا بالحالة الصحيحة.

حالة مصغرة متسلسلة — ساليم يستبدل سلسلة if بإكسبريس

ساليم، مطور مبتدئ في الجزائر، يقدم فهرسا مصغرا بالوحدة http الأصلية : سلسلة من if على req.url و req.method، وجسم POST يُحلل يدويا، وترويسات توضع واحدة واحدة. يعيد كتابة كل ذلك مع إكسبريس (Express) : ‏app.use(express.json())‏ لتحليل الجسم، و ‏app.get('/produits/:id')‏ للبطاقات الديناميكية، ووسيط (middleware) يسجل كل طلب، و ‏res.status(201).json()‏ للإنشاءات. نفس الخادم، وكود أوضح بثلاث مرات.

هذه الحالة نفسها تعود في الدرس والمخطط والنص الجاهز وتحدي 48 ساعة.

1. التوجيه (routing) و req/res المُثراة

إكسبريس (Express) هو إطار الوب المرجعي لنود : بسيط ومرن، ومبني على الوحدة http (القسم 2-4). التوجيه (routing) يربط طريقة HTTP وعنوان URL بمعالج : app.get('/users', handler)، و app.post('/users', handler)، ومثلها لـ put و patch و delete. الطرق الديناميكية تلتقط مقاطع : app.get('/users/:id') يجعل المعرف مقروءا في req.params.id.

الكائنات مُثراة مقارنة بالأصلي. جهة الطلب : req.params (معاملات الطريق)، و req.query (سلسلة الاستعلام بعد ؟)، و req.body (الجسم المحلل، المتاح بفضل express.json()). جهة الرد : res.json(data) يرسل JSON بطريقة واحدة، و res.status(201).json(...) يثبت الحالة ثم يرسل، و res.send و res.redirect يغطيان الحالات الأخرى. يربح ساليم الأساسي : لا تحليل يدوي بعد، وطرق مقروءة، وردود صريحة.

2. الوسيط (middleware) : خط ترتيبه مهم

الوسيط (middleware) هو المفهوم المفتاح في إكسبريس : دالة (req, res, next) تُنفَّذ أثناء معالجة طلب. يمكنها فحص req و res أو تعديلهما (إرفاق req.user بعد المصادقة)، وتنفيذ كود (التسجيل والتحقق والقياس)، ثم مناداة next() للمرور إلى الوسيط التالي — أو إرسال رد لوقف السلسلة (مثلا إرجاع 401 دون الذهاب أبعد).

يعبر كل طلب خط أنابيب (pipeline) بترتيب الإعلان : express.json() الذي يحلل الجسم، ووسائطكم (السجل والمصادقة والتحقق)، ثم المعالج النهائي الذي يرد. كل شيء وسيط : التحليل والملفات الثابتة والمصادقة وتدبير الأخطاء. ومنعكسا ساليم : الحلل قبل التحقق (وإلا فـ req.body فارغ) و مناداة next() أو الرد دائما (وإلا بقي الطلب عالقا). نطبق وسيطا عموما (app.use(...)) أو على طريق دقيق.

خطأ شائع في الفهم: « إكسبريس يعوض نود والوسيط اختياري، ويمكن نسيان next() ». لا. إكسبريس يستند إلى الوحدة http ولا يفعل سوى تلبسيها ؛ ووسيط لا ينادي لا next() ولا res.json()/res.send() يترك الطلب معلقا حتى المهلة. والترتيب (الحلل، ثم التحقق، ثم الرد) جزء من العقد.
خط إكسبريس كل طلب يعبر وسائط بالترتيب طلب GET /produits/:idexpress.json() يحللالجسموسائط السجل والمصادقةوالتحقق + next()معالج res.json /res.status().json
كل طلب يعبر وسائط بالترتيب
نص المخطط (SEO / قارئات الشاشة / الترجمة): 1) الطلب : يستقبل ساليم GET /produits/7 على خادمه في الجزائر. 2) التحليل : يهيئ express.json() الـ req.body لطلبات POST. 3) الوسائط : مسجله يدون الطلب ثم ينادي next()، ومراقبه يتحقق من البيانات. 4) المعالج : يقرأ الطريق الديناميكي req.params.id ويرد بـ res.json(). الدرس : ترتيب حلل ← تحقق ← رد يجعل الـ API موثوقة.

الحلقة المفقودة

« نسيت next() وطلبي ذهب في عطلة. »
جملة لا تُقال إلا مرة واحدة أمام طرفيتك

وسيط لا يمرر المهمة يعلق الجميع.

🔎 مثال ملموس — API فهرس مصغرة في أسطر قليلة

يعيد ساليم كتابة خادمه الأصلي مع إكسبريس.

const express = require('express');
const app = express();
app.use(express.json());
app.use((req, res, next) => { console.log(req.method, req.url); next(); });
app.get('/produits/:id', (req, res) => res.json({ id: req.params.id }));
app.post('/produits', (req, res) => res.status(201).json(req.body));
app.listen(3000);

القراءة : المسجل ينادي next()، والطريق الديناميكي يقرأ req.params، والإنشاء يرجع 201.

الدرس : التحليل التلقائي يحذف كل كود الخادم الأصلي اليدوي.

مفردات القسم

إكسبريس (Express)
إطار وب بسيط مرجعي لنود، مبني على الوحدة http ؛ يجلب التوجيه والوسائط و req/res المُثراة.

مثال بسيط: يعيد ساليم فيه كتابة فهرسه في أسطر قليلة مقروءة.

ما ليس كذلك: معوض لنود يستغني عن الوحدة http.

رد فعل: استعماله لكل API أو تطبيق وب بدل الأصلي الخام.

التوجيه (routing)
ربط طريقة HTTP وعنوان URL بمعالج : ‏app.get('/users', ...)‏ و ‏app.post(...)‏، مع طرق ديناميكية '/users/:id'.

مثال بسيط: ‏GET /produits/7‏ الملتقط بـ ‏app.get('/produits/:id')‏.

ما ليس كذلك: سلسلة من if على req.url في خادم أصلي.

رد فعل: طريق لكل نية، بالفعل الصحيح لـ HTTP.

الوسيط (middleware)
دالة (req, res, next) تُنفَّذ أثناء المعالجة ؛ تتصرف في req/res ثم تنادي next() أو ترسل ردا.

مثال بسيط: مسجل ساليم الذي يدون كل طلب ثم يمرر المهمة.

ما ليس كذلك: مجرد دالة نفعية غير مربوطة أبدا بالخط.

رد فعل: الإنهاء دائما بـ next() أو برد.

خط الوسائط
سلسلة مرتبة من الوسائط يعبرها كل طلب : التحليل والسجل والمصادقة والتحقق والمعالج النهائي.

مثال بسيط: ‏express.json()‏ ثم التحقق ثم المعالج عند ساليم.

ما ليس كذلك: معالجات معزولة دون ترتيب ولا اشتراك.

رد فعل: الحلل أولا، ثم التحقق، والرد أخيرا.

req / res المُثراة
كائنا إكسبريس : ‏req.params و req.query و req.body‏ جهة الطلب ؛ و ‏res.json و res.status و res.send و res.redirect‏ جهة الرد.

مثال بسيط: ‏req.params.id‏ مقروء و ‏res.status(201).json()‏ مرسَل.

ما ليس كذلك: الـ req/res الخام للوحدة http دون مساعدة.

رد فعل: قراءة الجسم في req.body، والرد مع res.json().

في التطبيق — بناء تطبيق مع إكسبريس

  1. أنشئوا تطبيق إكسبريس (‏const app = express()‏)، وأضيفوا ‏app.use(express.json())‏ لتحليل JSON، واشغلوا مع ‏app.listen(3000)‏.
  2. عرفوا طرقا : ‏app.get('/users', ...)‏ و ‏app.post('/users', ...)‏، وطريقا ديناميكيا ‏app.get('/users/:id', ...)‏ (اقرؤوا req.params.id).
  3. أرجعوا ردودا بالطرق المُثراة : ‏res.json(data)‏ و ‏res.status(201).json(...)‏، واقرؤوا الجسم مع req.body.
  4. اكتبوا وسيطكم الخاص (req, res, next) الذي يسجل كل طلب، وطبقوه مع ‏app.use(...)‏ ونادوا next().
تبنون تطبيقا/API مع إكسبريس : التوجيه (بما فيه الطرق الديناميكية)، و req/res المُثراة، والوسائط — قلب تطوير وب Node.

نص جاهز للقول — عرض API إكسبريس (30 ثانية)

« بنيت API الفهرس مع إكسبريس : ‏express.json‏ لتحليل الجسم، وطريق ديناميكي /produits/:id مقروء في req.params، ووسيط يسجل ثم ينادي next، وردود res.json بالحالة الصحيحة، 201 للإنشاءات. مُختبَر في المتصفح على localhost:3000. »

يُقال في المراجعة ؛ وتُعرَض الطريق الديناميكية وسجل طلب.

نموذج نسخ-لصق — خادم إكسبريس أدنى

const express = require('express');
const app = express();
app.use(express.json());
app.use((req, res, next) => {
  console.log(req.method, req.url);
  next();
});
app.get('/produits/:id', (req, res) => {
  res.json({ id: req.params.id });
});
app.post('/produits', (req, res) => {
  res.status(201).json(req.body);
});
app.listen(3000, () => console.log('OK port 3000'));

مستقل

تكفي API عروض أسعار بإكسبريس : طريقا GET/POST ووسيط سجل، دون إطار ثقيل.

مقاولة صغيرة في الجزائر

يعرض ساليم الفهرس الداخلي : طرق ديناميكية حسب مرجع المنتج، وحالات 200/201/404 محترَمة.

فريق منتج

توحيد الخط (json والسجل والمصادقة والتحقق) ليرث كل طريق نفس الأساس.

مبتدئ

هذا الأسبوع : خادم واحد، وطريق GET ديناميكية واحدة، ووسيط واحد ينادي next().

✓ ممارسات جيدة

  • التفكير « خط أنابيب » : كل شيء وسيط، والترتيب مهم.
  • استعمال express.json() لتحليل الجسم، و res.json() للرد.
  • تغليف الاهتمامات العرضية (المصادقة والسجل) في وسائط قابلة لإعادة الاستعمال.

✗ أخطاء شائعة

  • نسيان مناداة next() (يبقى الطلب عالقا).
  • سوء ترتيب الوسائط (التحقق قبل التحليل).
  • وضع كل المنطق في معالج واحد بدل تركيب وسائط.

النقاط الأساسية

  • إكسبريس = إطار وب نود المرجعي (مبني على http) : يبسط التوجيه والتحليل وتدبير الطلبات.
  • التوجيه : ‏app.get/post/put/delete('/chemin', handler)‏ ؛ طرق ديناميكية /users/:id ← req.params.id.
  • الوسيط (req, res, next) هو المفهوم المفتاح : يتصرف أثناء المعالجة، ثم next() يمرر للتالي — خط أنابيب.
  • كل شيء وسيط : ‏express.json()‏ والثابت والمصادقة وتدبير الأخطاء ووسائطكم الخاصة (app.use أو لكل طريق).

تحدي 48 ساعة — طبّق غدا

ابنوا API إكسبريس واحدة مع طريق ديناميكية واحدة و وسيط سجل واحد ينادي next().

قائمة الخروج من القسم
  • أذكر دور next() دون تردد.
  • أقرأ req.params و req.query و req.body.
  • الـ API عندي ترد بـ res.json() بالحالة الصحيحة.
تقييم ذاتي 1-5 : هل وسائطي مرتبة (التحليل قبل التحقق) ؟هل ينادي كل وسيط next() أو يرد ؟

أسئلة شائعة

ما هو الوسيط بالضبط، ولماذا هو المفهوم المركزي لإكسبريس ؟

الوسيط دالة (req, res, next) تُنفَّذ أثناء معالجة طلب. يمكنه فحص الطلب، وتعديل req/res (مثلا إرفاق req.user)، وتنفيذ كود (التسجيل والتحقق)، ثم يقرر : مناداة next() للمرور للتالي، أو إرسال رد لوقف السلسلة (وسيط مصادقة يرجع 401). وهو مركزي لأن كل شيء وسيط في إكسبريس : التحليل (express.json()) والثابت والمصادقة والتحقق وتدبير الأخطاء — ومعالجات الطرق هي الحلقة الأخيرة. التفكير « خط مرتب » بدل « دوال معزولة » هو فهم إكسبريس.

لماذا إكسبريس شائع جدا، وهل توجد بدائل ؟

بسيط وغير مُملٍ (توجيه + وسائط، وحرية الهيكلة)، وسهل البدء، وناضج ومُجرَّب، ونظام ضخم من الوسائط ومعيار فعلي منتظر من مطور Node. حدوده (خيارات تُتخذ ذاتيا، ولا هيكلة مفروضة) تحفز بدائل مثل Fastify و Koa و NestJS في المشاريع الكبيرة. لكن للتعلم ثم الإنتاج السريع، يبقى إكسبريس الخيار الافتراضي — الذي يتقنه ساليم أولا في الجزائر.

تحقّق من فهمك

في وسيط إكسبريس، ماذا يفرض عقد (req, res, next) ؟

موارد إضافية (اختياري، للتعمّق أكثر)

اختبار المستوى 3أسئلة جديدة وأصعب للتحقق من مكتسباتك