Node.js: أساسيات Express
آخر تحديث: 2026-08-26
1. من HTTP الأصلي إلى Express
أمضت أليس ثلاثة أيام في كتابة واجهة برمجة تطبيقات (API) باستخدام وحدة HTTP الأصلية، لكن الكود كان طويلاً وصعب الصيانة — فقد اضطرت إلى تحليل عناوين URL يدويًّا، وكتابة مطابقات المسارات يدويًّا، ومعالجة نص الطلب سطراً سطراً. وبعد التحول إلى Express، تمكنت من تنفيذ نفس الوظيفة في 30 سطراً فقط من الكود، مع مسارات محددة بوضوح وبرمجيات وسيطة متسلسلة تلقائيًّا، مما أدى إلى زيادة كفاءة الصيانة بمقدار 10 أضعاف.
مقارنة بين كود HTTP الأصلي وكود Express
| المقارنة | HTTP الأصلي | Express |
|---|---|---|
| تعريف المسار | يدوي if/else مطابقة req.url |
إعلاني app.get('/path', fn) |
| تحليل نص الطلب | الاستماع يدويًّا لأحداث data/end وإنشاء مخزن مؤقت |
express.json() يتم ذلك في سطر واحد |
| تم إرسال الرد | res.writeHead() + res.end() |
res.json() / res.send() |
| ملف ثابت | قراءة الملف يدويًّا + تعيين نوع المحتوى | express.static('public') |
| البرامج الوسيطة | لا يوجد دعم مدمج | app.use() التركيب على غرار خط الأنابيب |
| حجم الكود (للوظائف المماثلة) | ~80 سطراً | ~30 سطراً |
- Express هو إطار العمل الأكثر شيوعًا على الويب لـ Node.js؛ فهو يعمل على تجريد التفاصيل الأساسية لوحدة HTTP.
- النهج التصريحي في التوجيه يجعل العلاقة بين عناوين URL والمعالجات واضحة على الفور
- تعمل آلية البرمجيات الوسيطة على فصل الاهتمامات: حيث يقوم كل من التسجيل والمصادقة والتحليل بأداء وظائفه الخاصة.
- يتضمن
json()وstatic()لتلبية احتياجي تطوير واجهات برمجة التطبيقات (API) الأكثر شيوعًا - يوفر نظام بيئي واسع النطاق مجموعة كبيرة من برامج الوسيطة (middleware) من جهات خارجية، وهي جاهزة للاستخدام فورًا دون الحاجة إلى أي إعدادات إضافية
2. التثبيت و«Hello World»
▶ مثال:(1) تهيئة المشروع وتثبيت Express
mkdir my-express-app && cd my-express-app
npm init -y
npm install express
▶ مثال:(2) نسخة مبسطة من «Hello World»
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Server running at http://localhost:3000');
});
node app.js
ما عليك سوى زيارة http://localhost:3000 في متصفحك لعرض Hello World!.
▶ مثال: إرجاع استجابة بتنسيق JSON
app.get('/api/hello', (req, res) => {
res.json({ message: 'Hello from Express!', status: 'ok' });
});
▶ مثال: «Hello» مع معلمات التوجيه
app.get('/hello/:name', (req, res) => {
res.send(`Hello, ${req.params.name}!`);
});
3. طرق التوجيه
دليل مرجعي سريع لطرق التوجيه السريع
| الطريقة | الغرض | القابلية للتكرار | السيناريوهات النموذجية |
|---|---|---|---|
app.get() |
الحصول على الموارد | نعم | عرض القائمة/التفاصيل |
app.post() |
إنشاء مورد | لا | إرسال النموذج/إضافة سجل |
app.put() |
تحديث كامل | نعم | استبدال السجل بأكمله |
app.delete() |
حذف المورد | نعم | حذف السجل |
app.patch() |
تحديث جزئي | لا | تعديل الحقول الفردية |
app.all() |
Match all methods | — | General preprocessing |
▶ مثال:(1) التوجيه بنمط RESTful
app.get('/users', (req, res) => { res.json({ users: [] }); });
app.post('/users', (req, res) => { res.status(201).json({ created: true }); });
app.put('/users/:id', (req, res) => { res.json({ updated: req.params.id }); });
app.حذف('/users/:id', (req, res) => { res.json({ deleted: req.params.id }); });
(2) مطابقة المسار
- المطابقة التامة:
'/about'لا تتطابق إلا مع/about - تعيين المعلمات: يتم تعيين
'/users/:id'إلى/users/42، حيث تُحدد القيمة بواسطةreq.params.id - مطابقة أحرف البدل:
'/files/*'تتطابق مع/files/a/b/c
▶ مثال: قراءة معلمات الاستعلام
app.get('/search', (req, res) => {
const { q, page = '1' } = req.query;
res.json({ keyword: q, page: Number(page) });
});
▶ مثال: معلمات مسار متعددة
app.get('/posts/:postId/comments/:commentId', (req, res) => {
res.json(req.params);
});
4. مفهوم البرمجيات الوسيطة
يتمحور تصميم Express حول مسار البرمجيات الوسيطة — حيث يتدفق كل طلب بشكل تسلسلي عبر سلسلة من الدوال، يمكن لكل منها قراءة الطلب والاستجابة أو تعديلهما، أو إنهاء الطلب قبل الأوان.
flowchart LR A[Request Request] --> B[Middleware1<br/>Logging] B --> C[Middleware2<br/>JSONAnalysis] C --> D[Middleware3<br/>Authentication and Validation] D --> E[Route Handling<br/>Business Logic] E --> F[Response Response]
▶ مثال:(1) استخدام app.use() لتسجيل البرامج الوسيطة
const logger = (req, res, next) => {
console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`);
next();
};
app.use(logger);
(2) ترتيب تنفيذ البرامج الوسيطة
app.use()التنفيذ حسب ترتيب التسجيل؛ الموضع هو الذي يحدد المنطق- عند استدعاء
next()، يتم نقل التحكم إلى البرمجية الوسيطة التالية - إذا لم يتم استدعاء
next()، فسيتم تعليق الطلب؛ ويجب عليك إرسال الرد بنفسك.
▶ مثال: برمجيات وسيطة للمصادقة
const auth = (req, res, next) => {
const token = req.headers['authorization'];
if (!token) return res.status(401).json({ error: 'No token' });
next();
};
app.use('/api', auth);
▶ مثال: برامج الوسيطة لمعالجة الأخطاء
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something went wrong!' });
});
5. البرامج الوسيطة المدمجة
قائمة برامج الوساطة المدمجة
| البرامج الوسيطة | الغرض | التنفيذ | التكوينات الشائعة |
|---|---|---|---|
express.json() |
تحليل نص طلب JSON | app.use(express.json()) |
{ limit: '10kb' } |
express.urlencoded() |
تحليل نصوص الطلبات المشفرة بتنسيق URL | app.use(express.urlencoded({ extended: true })) |
{ extended: true/false } |
express.static() |
استضافة الملفات الثابتة | app.use(express.static('public')) |
{ maxAge: '1d' } |
▶ مثال:(1) تحليل نص الطلب باستخدام express.json()
app.use(express.json());
app.post('/api/users', (req, res) => {
console.log(req.body);
res.json({ received: req.body });
});
(2) express.static() لتقديم الملفات الثابتة
الهيكل المفترض للمشروع:
my-express-app/
├── public/
│ ├── index.html
│ └── style.css
├── app.js
└── package.json
app.use(express.static('public'));
تفضل بزيارة http://localhost:3000/index.html لتحميل الملفات الثابتة مباشرةً.
▶ مثال: الاستضافة الثابتة مع دلائل متعددة
app.use(express.static('public'));
app.use('/uploads', express.static('uploads'));
▶ مثال: تحديد حجم نص طلب JSON
app.use(express.json({ limit: '100kb' }));
6. إعادة التحميل التلقائي باستخدام nodemon
مقارنة بين nodemon و node
| عنصر المقارنة | node |
nodemon |
|---|---|---|
| بعد إجراء تغييرات على الملف | إعادة التشغيل يدويًّا | إعادة التشغيل تلقائيًّا |
| طريقة التركيب | مدمج | npm i -D nodemon |
| أمر التشغيل | node app.js |
npx nodemon app.js |
| بيئة الإنتاج | ينطبق | لا ينطبق |
| دليل المراقبة | لا شيء | الافتراضي: الدليل الحالي؛ قابل للتعديل |
▶ مثال:(1) التركيب والاستخدام
npm install --save-dev nodemon
npx nodemon app.js
▶ مثال:(2) تكوين البرامج النصية في ملف package.json
{
"scripts": {
"dev": "nodemon app.js",
"start": "node app.js"
}
}
استخدم npm run dev (إعادة التحميل التلقائي) أثناء مرحلة التطوير، وnpm start (التشغيل المستقر) في مرحلة الإنتاج.
▶ مثال: دليل المراقبة المخصص
npx nodemon --watch src --ext js,ets app.js
7. مثال شامل: تطبيق Express API
دعونا نربط بين جميع المفاهيم التي تناولناها حتى الآن ونبني تطبيقًا كاملاً لواجهة برمجة التطبيقات (API) على نطاق صغير من الصفر.
const express = require('express');
const app = express();
app.use(express.json());
app.use(express.static('public'));
let todos = [
{ id: 1, task: 'Learn Express', done: false },
{ id: 2, task: 'Build an API', done: false },
];
app.get('/api/todos', (req, res) => res.json(todos));
app.post('/api/todos', (req, res) => {
const todo = { id: todos.length + 1, ...req.body, done: false };
todos.push(todo);
res.status(201).json(todo);
});
app.put('/api/todos/:id', (req, res) => {
const idx = todos.findIndex(t => t.id === Number(req.params.id));
if (idx === -1) return res.status(404).json({ error: 'Not found' });
todos[idx] = { ...todos[idx], ...req.body };
res.json(todos[idx]);
});
app.delete('/api/todos/:id', (req, res) => {
todos = todos.filter(t => t.id !== Number(req.params.id));
res.json({ deleted: true });
});
app.listen(3000, () => console.log('API running at http://localhost:3000'));
بمجرد أن يصبح النظام جاهزًا للعمل، يمكنك الوصول إلى الصفحات الثابتة باستخدام متصفح، واستخدام أداة واجهة برمجة التطبيقات (API) لإجراء عمليات CRUD على /api/todos.
- بعد تثبيت Express، استخدم
express.json()وexpress.static()للتعامل مع تحليل نص الطلب (request body) واستضافة الملفات الثابتة في سطر واحد - توجيه RESTful
GET/POST/PUT/DELETEيغطي دورة CRUD الكاملة - أثناء عملية التطوير، تدخل التغييرات التي يتم إجراؤها على الكود بالتعاون مع
nodemonحيز التنفيذ تلقائيًّا؛ ولا يلزم إعادة التشغيل يدويًّا.
❓ أسئلة شائعة
app.use وapp.get؟app.use تتطابق مع جميع طرق الطلبات (request) وتُستخدم عادةً في البرامج الوسيطة (middleware)؛ أما app.get فتتطابق مع طلبات GET فقط وتُستخدم لتعريف المسارات (routes).app.use أو app.get. ويؤدي استدعاء next() إلى الانتقال إلى البرنامج الوسيط التالي؛ أما إذا لم يتم استدعاء next()، فيتوقف التنفيذ.س: هل «Express» هو الخيار الوحيد؟ ج: لا. فـ«Koa» أخف وزنًا، و«Fastify» أسرع، و«Hono» يدعم الحوسبة الطرفية، لكن «Express» يتمتع بنظام بيئي أكثر نضجًا وبأكبر عدد من موارد التعلم، مما يجعله الخيار الأفضل للمبتدئين.
س: هل يجب استدعاء express.json() قبل الروت؟ ج: نعم، يجب كتابة app.use(express.json()) قبل الروت؛ وإلا فإن req.body ستصبح indefinido، لأن البرامج الوسيطة تُنفَّذ بالترتيب الذي تم تسجيلها به.
س: ما الفرق بين الإصدار 4.x والإصدار 5.x؟ ج: يزيل Express 5.x واجهات برمجة التطبيقات (API) التي لم تعد مستخدمة (مثل app.del)، ويحسن مطابقة الروت (مع دعم path-to-regexp v8)، ويجعل بعض السلوكيات أكثر توافقًا مع العمليات غير المتزامنة، لكن طريقة الاستخدام الأساسية تظل كما هي إلى حد كبير.
س: كيف يمكنني إعادة تشغيل الخدمة تلقائيًا؟ ج: قم بتثبيت nodemon (npm i -D nodemon)، وقم بتشغيلها باستخدام npx nodemon app.js، وستُعاد تشغيلها تلقائيًا بعد حفظ الملف — وهو أمر فعال للغاية أثناء مرحلة التطوير.
س: ما الفرق بين app.use وapp.get؟ ج: app.use تتطابق مع جميع طرق HTTP وتتطابق مع بادئة المسار (/api تتطابق مع /api/anything)، بينما app.get تتطابق فقط مع طريقة GET وتتطلب تطابقًا دقيقًا للمسار. يُستخدم الأول في البرامج الوسيطة، بينما يُستخدم الثاني في التوجيه.
س: ما معنى الخيار extended في express.urlencoded؟ ج: يستخدم extended: true مكتبة qs للتحليل (يدعم الكائنات المتداخلة)، ويستخدم extended: false مكتبة querystring (لا يدعم الكائنات المتداخلة)، أما true فهو كافٍ عمومًا لإرسال النماذج.
📖 ملخص
- 1 المفاهيم الأساسية لاستخدام Express، من HTTP الأصلي إلى Express
- 2 التثبيت والمفاهيم الأساسية واستخدام "Hello World"
- 3 المفاهيم الأساسية وطرق استخدام طرق التوجيه
- 4 المفاهيم الأساسية للبرمجيات الوسيطة واستخداماتها
- 5 مفاهيم أساسية واستخدامات البرمجيات الوسيطة المدمجة
- 6 مفاهيم أساسية واستخدامات Nodemon Hot Reload
- 7 مثال شامل: المفاهيم الأساسية واستخدامات تطبيق واجهة برمجة التطبيقات (API) من Express
📝 تمارين
- أكمل جميع أمثلة الأكواد الواردة في هذا الدرس وتأكد من أن كل منها يعمل بشكل صحيح.
- قم بتعديل المثال الشامل وأضف الإضافات الخاصة بك
- راجع الوثائق الرسمية، وحدد واجهة برمجة تطبيقات (API) واحدة أو اثنتين لم يتم تناولهما في هذا الدرس، واكتب كود اختبار لهما.
- التأمل: كيف ستطبق ما تعلمته في هذا الدرس على مشروع في الواقع العملي؟
- حاول أن تجمع بين ما تعلمته في هذا الدرس والمواد التي درستها في الدروس السابقة لـ build مشروعًا صغيرًا.