Node.js
مقدمة في Express.js — دليل شامل 2026
📅 2026-11-06⏱ 9 دقائق قراءة
في المقال السابق، بنيت HTTP Server من الصفر. الآن سنتعلم **Express.js** — الإطار الذي يجعل بناء السيرفرات **أسهل بكثير**.
في هذا الدليل العملي، سنأخذك خطوة بخطوة لتعلم Express.js، مع تمارين وحلول.
## ما هو Express.js؟
**Express.js** هو **إطار عمل (Framework)** مبني على Node.js، يبسّط بناء السيرفرات والتطبيقات.
**تشبيه بسيط:** إذا كان Node.js هو **المحرك**، فإن Express هو **السيارة الكاملة** — جاهزة للقيادة.
## لماذا Express؟
قبل أن نبدأ، دعنا نتفق على الأسباب:
- **بسيط:** كود أقل بكثير من HTTP الخام.
- **مرن:** يمكن إضافة أي مكتبة.
- **شائع:** الأكثر استخداماً في Node.js.
- **مميزات جاهزة:** Routing، Middleware، Static Files.
- **مجتمع ضخم:** مصادر لا تنتهي.
## الفرق بين HTTP الخام و Express
### HTTP الخام:
```javascript
const http = require("http");
http.createServer((req, res) => {
if (req.method === "GET" && req.url === "/") {
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
res.end("<h1>مرحباً</h1>");
} else if (req.method === "GET" && req.url === "/about") {
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
res.end("<h1>من نحن</h1>");
} else {
res.writeHead(404);
res.end("404");
}
}).listen(3000);
```
### مع Express:
```javascript
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.send("<h1>مرحباً</h1>");
});
app.get("/about", (req, res) => {
res.send("<h1>من نحن</h1>");
});
app.listen(3000);
```
**الفرق:** Express **أوضح** و **أقصر** بكثير.
## تثبيت Express
```bash
npm install express
```
## أول تطبيق Express
**`index.js`:**
```javascript
const express = require("express");
const app = express();
const PORT = 3000;
// المسار الرئيسي
app.get("/", (req, res) => {
res.send("مرحباً من Express! 🎉");
});
// تشغيل السيرفر
app.listen(PORT, () => {
console.log(`🚀 السيرفر يعمل على http://localhost:${PORT}`);
});
```
**التشغيل:**
```bash
node index.js
```
افتح المتصفح على `http://localhost:3000` — سترى:
```
مرحباً من Express! 🎉
```
**🎉 مبروك! بنيت أول تطبيق Express!**
## المسارات (Routes)
**المسار** = Method + Path + Handler.
```javascript
app.METHOD(PATH, HANDLER);
```
### 1. GET
```javascript
app.get("/", (req, res) => {
res.send("الصفحة الرئيسية");
});
```
### 2. POST
```javascript
app.post("/users", (req, res) => {
res.send("تم إنشاء مستخدم");
});
```
### 3. PUT
```javascript
app.put("/users/:id", (req, res) => {
res.send(`تم تحديث المستخدم ${req.params.id}`);
});
```
### 4. DELETE
```javascript
app.delete("/users/:id", (req, res) => {
res.send(`تم حذف المستخدم ${req.params.id}`);
});
```
### 5. جميع الطرق
```javascript
app.all("/secret", (req, res) => {
res.send("محمي");
});
```
## جدول طرق HTTP
<table>
<thead>
<tr>
<th>الطريقة</th>
<th>الوظيفة</th>
<th>الاستخدام</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>GET</strong></td>
<td>قراءة</td>
<td>جلب بيانات</td>
</tr>
<tr>
<td><strong>POST</strong></td>
<td>إنشاء</td>
<td>إضافة جديدة</td>
</tr>
<tr>
<td><strong>PUT</strong></td>
<td>تحديث كامل</td>
<td>استبدال</td>
</tr>
<tr>
<td><strong>PATCH</strong></td>
<td>تحديث جزئي</td>
<td>تعديل بعض الحقول</td>
</tr>
<tr>
<td><strong>DELETE</strong></td>
<td>حذف</td>
<td>إزالة</td>
</tr>
</tbody>
</table>
## `req` و `res`
### `req` (Request)
<table>
<thead>
<tr>
<th>الخاصية</th>
<th>الوصف</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>req.params</code></td>
<td>معاملات URL</td>
</tr>
<tr>
<td><code>req.query</code></td>
<td>Query String</td>
</tr>
<tr>
<td><code>req.body</code></td>
<td>بيانات POST</td>
</tr>
<tr>
<td><code>req.method</code></td>
<td>طريقة HTTP</td>
</tr>
<tr>
<td><code>req.url</code></td>
<td>الرابط</td>
</tr>
<tr>
<td><code>req.headers</code></td>
<td>الرؤوس</td>
</tr>
</tbody>
</table>
### `res` (Response)
<table>
<thead>
<tr>
<th>الدالة</th>
<th>الوظيفة</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>res.send()</code></td>
<td>إرسال نص/HTML</td>
</tr>
<tr>
<td><code>res.json()</code></td>
<td>إرسال JSON</td>
</tr>
<tr>
<td><code>res.status()</code></td>
<td>تعيين كود الحالة</td>
</tr>
<tr>
<td><code>res.redirect()</code></td>
<td>إعادة توجيه</td>
</tr>
<tr>
<td><code>res.sendFile()</code></td>
<td>إرسال ملف</td>
</tr>
<tr>
<td><code>res.download()</code></td>
<td>تحميل ملف</td>
</tr>
</tbody>
</table>
## إرسال JSON
```javascript
app.get("/api/users", (req, res) => {
res.json([
{ id: 1, name: "أحمد" },
{ id: 2, name: "محمد" },
]);
});
```
**النتيجة:** JSON تلقائياً مع `Content-Type: application/json`.
## معاملات URL (Route Parameters)
```javascript
app.get("/users/:id", (req, res) => {
const id = req.params.id;
res.send(`المستخدم رقم ${id}`);
});
```
**النتيجة:**
- `/users/1` → "المستخدم رقم 1"
- `/users/42` → "المستخدم رقم 42"
### عدة معاملات:
```javascript
app.get("/users/:userId/posts/:postId", (req, res) => {
const { userId, postId } = req.params;
res.send(`المستخدم ${userId}، المقال ${postId}`);
});
```
## Query Strings
```javascript
app.get("/search", (req, res) => {
const { q, limit } = req.query;
res.json({ query: q, limit: limit || 10 });
});
```
**الرابط:** `/search?q=react&limit=5`
**النتيجة:**
```json
{ "query": "react", "limit": "5" }
```
## قراءة `body` (POST)
**⚠️ مهم:** Express لا يقرأ `body` تلقائياً. استخدم Middleware:
```javascript
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
```
**ثم:**
```javascript
app.post("/api/users", (req, res) => {
const { name, email } = req.body;
res.status(201).json({
success: true,
user: { name, email },
});
});
```
## تقديم الملفات الثابتة
```javascript
app.use(express.static("public"));
```
**النتيجة:** أي ملف في `public/` يصبح متاحاً:
- `public/style.css` → `/style.css`
- `public/script.js` → `/script.js`
## Middleware
**Middleware** هي دوال تُنفَّذ **قبل** المسار.
```javascript
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next(); // ← مهم: للانتقال للمرحلة التالية
});
```
**الأنواع:**
<table>
<thead>
<tr>
<th>النوع</th>
<th>الوصف</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Application-level</strong></td>
<td>على كل التطبيق</td>
</tr>
<tr>
<td><strong>Router-level</strong></td>
<td>على Router معين</td>
</tr>
<tr>
<td><strong>Error-handling</strong></td>
<td>لمعالجة الأخطاء</td>
</tr>
<tr>
<td><strong>Built-in</strong></td>
<td>مدمج (express.json)</td>
</tr>
<tr>
<td><strong>Third-party</strong></td>
<td>خارجي (cors, morgan)</td>
</tr>
</tbody>
</table>
### مثال: Middleware للمصادقة
```javascript
function auth(req, res, next) {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: "غير مصرح" });
}
next();
}
app.get("/admin", auth, (req, res) => {
res.send("لوحة التحكم");
});
```
## معالجة الأخطاء
### 404 Not Found
```javascript
app.use((req, res) => {
res.status(404).json({ error: "المسار غير موجود" });
});
```
### Error Handler
```javascript
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: "خطأ في السيرفر" });
});
```
**⚠️ مهم:** Error Handler يجب أن يكون **بعد** كل المسارات، وله **4 معاملات**.
## مثال عملي: API للمهام
```javascript
const express = require("express");
const app = express();
app.use(express.json());
let todos = [
{ id: 1, text: "تعلم Express", completed: false },
{ id: 2, text: "بناء API", completed: true },
];
// جلب كل المهام
app.get("/api/todos", (req, res) => {
res.json(todos);
});
// جلب مهمة واحدة
app.get("/api/todos/:id", (req, res) => {
const todo = todos.find((t) => t.id === parseInt(req.params.id));
if (!todo) return res.status(404).json({ error: "غير موجودة" });
res.json(todo);
});
// إضافة مهمة
app.post("/api/todos", (req, res) => {
const { text } = req.body;
if (!text) return res.status(400).json({ error: "النص مطلوب" });
const newTodo = { id: Date.now(), text, completed: false };
todos.push(newTodo);
res.status(201).json(newTodo);
});
// تحديث مهمة
app.put("/api/todos/:id", (req, res) => {
const todo = todos.find((t) => t.id === parseInt(req.params.id));
if (!todo) return res.status(404).json({ error: "غير موجودة" });
todo.text = req.body.text || todo.text;
todo.completed = req.body.completed ?? todo.completed;
res.json(todo);
});
// حذف مهمة
app.delete("/api/todos/:id", (req, res) => {
const id = parseInt(req.params.id);
todos = todos.filter((t) => t.id !== id);
res.status(204).send();
});
// معالج 404
app.use((req, res) => {
res.status(404).json({ error: "المسار غير موجود" });
});
app.listen(3000, () => console.log("🚀 على http://localhost:3000"));
```
## تمارين عملية
### تمرين 1: سيرفر بسيط
أنشئ سيرفر Express يعيد "مرحباً".
**الحل:**
```javascript
const express = require("express");
const app = express();
app.get("/", (req, res) => res.send("مرحباً"));
app.listen(3000);
```
### تمرين 2: 3 مسارات
أنشئ 3 مسارات: `/`, `/about`, `/contact`.
**الحل:**
```javascript
app.get("/", (req, res) => res.send("الرئيسية"));
app.get("/about", (req, res) => res.send("من نحن"));
app.get("/contact", (req, res) => res.send("اتصل بنا"));
```
### تمرين 3: JSON
أعد مصفوفة مستخدمين كـ JSON.
**الحل:**
```javascript
app.get("/api/users", (req, res) => {
res.json([
{ id: 1, name: "أحمد" },
{ id: 2, name: "محمد" },
]);
});
```
### تمرين 4: معامل URL
أنشئ مسار `/users/:id` يعيد رقم المستخدم.
**الحل:**
```javascript
app.get("/users/:id", (req, res) => {
res.send(`المستخدم: ${req.params.id}`);
});
```
### تمرين 5: Query String
أنشئ مسار `/search` يقرأ `q`.
**الحل:**
```javascript
app.get("/search", (req, res) => {
res.json({ query: req.query.q });
});
```
### تمرين 6: POST
أنشئ POST يقبل JSON ويعيده.
**الحل:**
```javascript
app.use(express.json());
app.post("/echo", (req, res) => {
res.json(req.body);
});
```
### تمرين 7: Middleware
أضف Middleware يسجّل كل طلب.
**الحل:**
```javascript
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
```
### تمرين 8: API كامل
ابنِ API كامل (CRUD) لـ "كتب".
**الحل:**
```javascript
const express = require("express");
const app = express();
app.use(express.json());
let books = [];
let nextId = 1;
// جلب كل الكتب
app.get("/api/books", (req, res) => res.json(books));
// جلب كتاب
app.get("/api/books/:id", (req, res) => {
const book = books.find((b) => b.id === parseInt(req.params.id));
if (!book) return res.status(404).json({ error: "غير موجود" });
res.json(book);
});
// إضافة كتاب
app.post("/api/books", (req, res) => {
const book = { id: nextId++, ...req.body };
books.push(book);
res.status(201).json(book);
});
// تحديث كتاب
app.put("/api/books/:id", (req, res) => {
const book = books.find((b) => b.id === parseInt(req.params.id));
if (!book) return res.status(404).json({ error: "غير موجود" });
Object.assign(book, req.body);
res.json(book);
});
// حذف كتاب
app.delete("/api/books/:id", (req, res) => {
books = books.filter((b) => b.id !== parseInt(req.params.id));
res.status(204).send();
});
app.listen(3000);
```
## حل المشاكل الشائعة
### 🔴 المشكلة 1: `Cannot find module 'express'`
**الحل:**
```bash
npm install express
```
### 🔴 المشكلة 2: `req.body is undefined`
**الحل:** أضف Middleware:
```javascript
app.use(express.json());
```
### 🔴 المشكلة 3: `EADDRINUSE`
**الحل:** استخدم منفذاً آخر:
```javascript
const PORT = process.env.PORT || 3001;
```
### 🔴 المشكلة 4: CORS Error
**الحل:**
```bash
npm install cors
```
```javascript
const cors = require("cors");
app.use(cors());
```
### 🔴 المشكلة 5: 404 دائماً
**السبب:** `app.use()` لـ 404 قبل المسارات.
**الحل:** ضع معالج 404 **بعد** كل المسارات.
## جدول دوال Express
<table>
<thead>
<tr>
<th>الدالة</th>
<th>الوظيفة</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>app.get()</code></td>
<td>مسار GET</td>
</tr>
<tr>
<td><code>app.post()</code></td>
<td>مسار POST</td>
</tr>
<tr>
<td><code>app.put()</code></td>
<td>مسار PUT</td>
</tr>
<tr>
<td><code>app.delete()</code></td>
<td>مسار DELETE</td>
</tr>
<tr>
<td><code>app.use()</code></td>
<td>Middleware</td>
</tr>
<tr>
<td><code>app.listen()</code></td>
<td>تشغيل السيرفر</td>
</tr>
<tr>
<td><code>res.send()</code></td>
<td>إرسال نص</td>
</tr>
<tr>
<td><code>res.json()</code></td>
<td>إرسال JSON</td>
</tr>
<tr>
<td><code>res.status()</code></td>
<td>كود الحالة</td>
</tr>
<tr>
<td><code>res.sendFile()</code></td>
<td>إرسال ملف</td>
</tr>
</tbody>
</table>
## قائمة تحقق نهائية
<table>
<thead>
<tr>
<th>المهمة</th>
<th>الحالة</th>
</tr>
</thead>
<tbody>
<tr>
<td>تثبيت Express</td>
<td>⬜</td>
</tr>
<tr>
<td>إنشاء أول سيرفر Express</td>
<td>⬜</td>
</tr>
<tr>
<td>فهم المسارات (GET, POST, ...)</td>
<td>⬜</td>
</tr>
<tr>
<td>استخدام req.params و req.query</td>
<td>⬜</td>
</tr>
<tr>
<td>إرسال JSON</td>
<td>⬜</td>
</tr>
<tr>
<td>Middleware</td>
<td>⬜</td>
</tr>
<tr>
<td>حل التمارين الثمانية</td>
<td>⬜</td>
</tr>
</tbody>
</table>
## ماذا بعد هذا المقال؟
الآن بعد أن أتقنت أساسيات Express، أنت جاهز للمقال التالي:
1. **Express Routing** — تنظيم المسارات.
2. **Middleware المتقدم** — معالجة متقدمة.
3. **بناء REST API** — واجهات احترافية.
## الخلاصة
في هذا المقال، تعلمت:
- ✅ ما هو Express ولماذا نحتاجه.
- ✅ تثبيت Express.
- ✅ المسارات (Routes).
- ✅ `req` و `res`.
- ✅ معاملات URL و Query Strings.
- ✅ Middleware.
- ✅ معالجة الأخطاء.
- ✅ بناء API كامل.
- ✅ حل 8 تمارين عملية.
**تذكر:** Express هو **الإطار الأكثر استخداماً** في Node.js. أتقنه جيداً.