Node.js
التوجيه و Middleware في Express.js — دليل شامل 2026
📅 2026-11-07⏱ 8 دقائق قراءة
في المقال السابق، تعلمت أساسيات Express.js. الآن سنتعمق في **التوجيه (Routing)** و **Middleware** — وهما ما يجعل تطبيقك **منظماً واحترافياً**.
في هذا الدليل العملي، سنأخذك خطوة بخطوة لفهم التوجيه والميدل وير، مع تمارين وحلول.
## ما هو التوجيه (Routing)؟
**التوجيه** هو تحديد **كيف يستجيب التطبيق** لطلبات المستخدم.
**الصيغة:**
```javascript
app.METHOD(PATH, HANDLER);
```
**مثال:**
```javascript
app.get("/users", (req, res) => {
res.json({ users: [] });
});
```
## مشكلة المسارات المتعددة
**عندما يكبر التطبيق:**
```javascript
// كل شيء في index.js
app.get("/users", ...);
app.post("/users", ...);
app.get("/users/:id", ...);
app.put("/users/:id", ...);
app.delete("/users/:id", ...);
app.get("/posts", ...);
app.post("/posts", ...);
// ... 100+ مسار
```
**المشكلة:** الملف يصبح **ضخماً** و **صعب الصيانة**.
## الحل: Express Router
**Express Router** يسمح بتقسيم المسارات إلى **ملفات منفصلة**.
### 1. بنية المشروع
```
my-app/
├── routes/
│ ├── users.js
│ ├── posts.js
│ └── products.js
├── index.js
└── package.json
```
### 2. إنشاء Router
**`routes/users.js`:**
```javascript
const express = require("express");
const router = express.Router();
// GET /users
router.get("/", (req, res) => {
res.json([{ id: 1, name: "أحمد" }]);
});
// POST /users
router.post("/", (req, res) => {
res.status(201).json({ success: true });
});
// GET /users/:id
router.get("/:id", (req, res) => {
res.json({ id: req.params.id });
});
module.exports = router;
```
### 3. استخدام Router في التطبيق
**`index.js`:**
```javascript
const express = require("express");
const app = express();
// استيراد Routes
const usersRouter = require("./routes/users");
const postsRouter = require("./routes/posts");
app.use(express.json());
// ربط Routes
app.use("/users", usersRouter);
app.use("/posts", postsRouter);
app.listen(3000, () => console.log("🚀 على http://localhost:3000"));
```
**النتيجة:**
- `GET /users` → يعمل
- `GET /users/1` → يعمل
- `POST /users` → يعمل
- `GET /posts` → يعمل
**🎉 الكود أصبح منظماً!**
## مثال كامل: 3 Routers
### `routes/users.js`:
```javascript
const express = require("express");
const router = express.Router();
let users = [
{ id: 1, name: "أحمد", email: "[email protected]" },
{ id: 2, name: "محمد", email: "[email protected]" },
];
// جلب كل المستخدمين
router.get("/", (req, res) => {
res.json(users);
});
// جلب مستخدم واحد
router.get("/:id", (req, res) => {
const user = users.find((u) => u.id === parseInt(req.params.id));
if (!user) return res.status(404).json({ error: "غير موجود" });
res.json(user);
});
// إضافة مستخدم
router.post("/", (req, res) => {
const { name, email } = req.body;
const newUser = { id: Date.now(), name, email };
users.push(newUser);
res.status(201).json(newUser);
});
// تحديث مستخدم
router.put("/:id", (req, res) => {
const user = users.find((u) => u.id === parseInt(req.params.id));
if (!user) return res.status(404).json({ error: "غير موجود" });
Object.assign(user, req.body);
res.json(user);
});
// حذف مستخدم
router.delete("/:id", (req, res) => {
users = users.filter((u) => u.id !== parseInt(req.params.id));
res.status(204).send();
});
module.exports = router;
```
### `routes/posts.js`:
```javascript
const express = require("express");
const router = express.Router();
let posts = [
{ id: 1, title: "تعلم Node.js", content: "..." },
{ id: 2, title: "تعلم Express", content: "..." },
];
router.get("/", (req, res) => {
res.json(posts);
});
router.get("/:id", (req, res) => {
const post = posts.find((p) => p.id === parseInt(req.params.id));
if (!post) return res.status(404).json({ error: "غير موجود" });
res.json(post);
});
router.post("/", (req, res) => {
const newPost = { id: Date.now(), ...req.body };
posts.push(newPost);
res.status(201).json(newPost);
});
module.exports = router;
```
### `index.js`:
```javascript
const express = require("express");
const app = express();
app.use(express.json());
app.use("/api/users", require("./routes/users"));
app.use("/api/posts", require("./routes/posts"));
app.listen(3000, () => console.log("🚀 على http://localhost:3000"));
```
## تنظيم متقدم: Controllers
**لفصل المنطق عن المسارات:**
```
my-app/
├── routes/
│ └── users.js
├── controllers/
│ └── userController.js
├── models/
│ └── user.js
└── index.js
```
### `controllers/userController.js`:
```javascript
let users = [
{ id: 1, name: "أحمد" },
];
exports.getAllUsers = (req, res) => {
res.json(users);
};
exports.getUserById = (req, res) => {
const user = users.find((u) => u.id === parseInt(req.params.id));
if (!user) return res.status(404).json({ error: "غير موجود" });
res.json(user);
};
exports.createUser = (req, res) => {
const newUser = { id: Date.now(), ...req.body };
users.push(newUser);
res.status(201).json(newUser);
};
exports.updateUser = (req, res) => {
const user = users.find((u) => u.id === parseInt(req.params.id));
if (!user) return res.status(404).json({ error: "غير موجود" });
Object.assign(user, req.body);
res.json(user);
};
exports.deleteUser = (req, res) => {
users = users.filter((u) => u.id !== parseInt(req.params.id));
res.status(204).send();
};
```
### `routes/users.js`:
```javascript
const express = require("express");
const router = express.Router();
const userController = require("../controllers/userController");
router.get("/", userController.getAllUsers);
router.get("/:id", userController.getUserById);
router.post("/", userController.createUser);
router.put("/:id", userController.updateUser);
router.delete("/:id", userController.deleteUser);
module.exports = router;
```
**الفائدة:** **Routes** للتوجيه فقط، **Controllers** للمنطق.
## Middleware المتقدم
### 1. Middleware للتسجيل
```javascript
function logger(req, res, next) {
const now = new Date().toISOString();
console.log(`[${now}] ${req.method} ${req.url}`);
next();
}
app.use(logger);
```
### 2. Middleware للمصادقة
```javascript
function auth(req, res, next) {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: "غير مصرح" });
}
try {
const decoded = jwt.verify(token, "secret");
req.user = decoded;
next();
} catch (error) {
res.status(401).json({ error: "توكن غير صالح" });
}
}
// استخدامه على مسار معين:
app.get("/profile", auth, (req, res) => {
res.json(req.user);
});
```
### 3. Middleware للتحقق
```javascript
function validateUser(req, res, next) {
const { name, email } = req.body;
if (!name || name.length < 2) {
return res.status(400).json({ error: "الاسم قصير" });
}
if (!email || !email.includes("@")) {
return res.status(400).json({ error: "البريد غير صحيح" });
}
next();
}
app.post("/users", validateUser, (req, res) => {
res.json({ success: true });
});
```
### 4. Middleware للمعدل (Rate Limiting)
```javascript
const rateLimit = require("express-rate-limit");
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 دقيقة
max: 100, // 100 طلب
message: "تم تجاوز الحد، حاول لاحقاً",
});
app.use("/api", limiter);
```
### 5. Middleware للأخطاء
```javascript
app.use((err, req, res, next) => {
console.error("خطأ:", err.message);
const status = err.status || 500;
res.status(status).json({
error: err.message || "خطأ في السيرفر",
});
});
```
## ترتيب Middleware
**⚠️ الترتيب مهم جداً!**
```javascript
const express = require("express");
const app = express();
// 1. Middleware عام
app.use(express.json());
app.use(logger);
app.use(cors());
// 2. Static files
app.use(express.static("public"));
// 3. Routes
app.use("/api/users", usersRouter);
app.use("/api/posts", postsRouter);
// 4. 404 (بعد كل المسارات)
app.use((req, res) => {
res.status(404).json({ error: "المسار غير موجود" });
});
// 5. Error Handler (الأخير دائماً)
app.use((err, req, res, next) => {
res.status(500).json({ error: err.message });
});
```
## Middleware مخصص
### 1. Middleware على مستوى التطبيق
```javascript
app.use((req, res, next) => {
req.startTime = Date.now();
next();
});
```
### 2. Middleware على مستوى Router
```javascript
const router = express.Router();
router.use((req, res, next) => {
console.log("Router middleware");
next();
});
```
### 3. Middleware على مسار محدد
```javascript
app.get("/admin", authMiddleware, (req, res) => {
res.send("لوحة التحكم");
});
```
## تمارين عملية
### تمرين 1: Router بسيط
أنشئ Router للمستخدمين.
**الحل:**
```javascript
// routes/users.js
const express = require("express");
const router = express.Router();
router.get("/", (req, res) => res.json([]));
router.post("/", (req, res) => res.status(201).json({}));
module.exports = router;
```
```javascript
// index.js
app.use("/api/users", require("./routes/users"));
```
### تمرين 2: 3 Routers
أنشئ Routers للمستخدمين والمنتجات والطلبات.
**الحل:**
```javascript
app.use("/api/users", require("./routes/users"));
app.use("/api/products", require("./routes/products"));
app.use("/api/orders", require("./routes/orders"));
```
### تمرين 3: Controller
افصل منطق المسار في Controller.
**الحل:**
```javascript
// controllers/userController.js
exports.getAll = (req, res) => res.json([]);
// routes/users.js
const ctrl = require("../controllers/userController");
router.get("/", ctrl.getAll);
```
### تمرين 4: Middleware للتسجيل
أضف Middleware يسجّل الوقت.
**الحل:**
```javascript
app.use((req, res, next) => {
console.log(new Date().toISOString(), req.method, req.url);
next();
});
```
### تمرين 5: Middleware للمصادقة
أضف Middleware يتحقق من توكن.
**الحل:**
```javascript
function auth(req, res, next) {
if (!req.headers.authorization) {
return res.status(401).json({ error: "غير مصرح" });
}
next();
}
app.get("/admin", auth, (req, res) => res.send("محمي"));
```
### تمرين 6: Middleware للتحقق
تحقق من بيانات المستخدم.
**الحل:**
```javascript
function validate(req, res, next) {
if (!req.body.name) {
return res.status(400).json({ error: "الاسم مطلوب" });
}
next();
}
```
### تمرين 7: 404 Handler
أضف معالج 404.
**الحل:**
```javascript
app.use((req, res) => {
res.status(404).json({ error: "غير موجود" });
});
```
### تمرين 8: API كامل
ابنِ API كامل مع Routers و Controllers.
**الحل:** (راجع المثال الكامل أعلاه)
## حل المشاكل الشائعة
### 🔴 المشكلة 1: Router لا يعمل
**السبب:** نسيت `app.use()`.
**الحل:**
```javascript
app.use("/api/users", usersRouter);
```
### 🔴 المشكلة 2: Middleware لا يعمل
**السبب:** لم تستدعِ `next()`.
**الحل:**
```javascript
function middleware(req, res, next) {
// ...
next(); // ← مهم
}
```
### 🔴 المشكلة 3: 404 لجميع المسارات
**السبب:** 404 Handler قبل المسارات.
**الحل:** ضعه **بعد** كل المسارات.
### 🔴 المشكلة 4: Error Handler لا يعمل
**السبب:** عدد المعاملات خاطئ.
**الحل:** يجب أن يكون **4 معاملات**:
```javascript
app.use((err, req, res, next) => { ... });
```
### 🔴 المشكلة 5: CORS
**الحل:**
```bash
npm install cors
```
```javascript
const cors = require("cors");
app.use(cors());
```
## جدول أنواع Middleware
<table>
<thead>
<tr>
<th>النوع</th>
<th>الوصف</th>
<th>مثال</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Application</strong></td>
<td>على كل التطبيق</td>
<td><code>app.use()</code></td>
</tr>
<tr>
<td><strong>Router</strong></td>
<td>على Router</td>
<td><code>router.use()</code></td>
</tr>
<tr>
<td><strong>Route</strong></td>
<td>على مسار محدد</td>
<td><code>app.get(path, mw)</code></td>
</tr>
<tr>
<td><strong>Error</strong></td>
<td>معالجة الأخطاء</td>
<td><code>(err, req, res, next)</code></td>
</tr>
<tr>
<td><strong>Built-in</strong></td>
<td>مدمج</td>
<td><code>express.json()</code></td>
</tr>
<tr>
<td><strong>Third-party</strong></td>
<td>خارجي</td>
<td><code>cors, morgan</code></td>
</tr>
</tbody>
</table>
## قائمة تحقق نهائية
<table>
<thead>
<tr>
<th>المهمة</th>
<th>الحالة</th>
</tr>
</thead>
<tbody>
<tr>
<td>فهم Express Router</td>
<td>⬜</td>
</tr>
<tr>
<td>إنشاء Routers منفصلة</td>
<td>⬜</td>
</tr>
<tr>
<td>فصل Controllers عن Routes</td>
<td>⬜</td>
</tr>
<tr>
<td>فهم Middleware</td>
<td>⬜</td>
</tr>
<tr>
<td>Middleware للمصادقة والتحقق</td>
<td>⬜</td>
</tr>
<tr>
<td>ترتيب Middleware الصحيح</td>
<td>⬜</td>
</tr>
<tr>
<td>حل التمارين الثمانية</td>
<td>⬜</td>
</tr>
</tbody>
</table>
## ماذا بعد هذا المقال؟
الآن بعد أن أتقنت التوجيه و Middleware، أنت جاهز للمقال التالي:
1. **بناء REST API** — واجهات احترافية.
2. **قواعد البيانات (MongoDB)** — تخزين البيانات.
3. **المصادقة (JWT)** — تسجيل الدخول.
## الخلاصة
في هذا المقال، تعلمت:
- ✅ Express Router.
- ✅ تنظيم المشروع (Routes, Controllers).
- ✅ Middleware المتقدم.
- ✅ ترتيب Middleware الصحيح.
- ✅ معالجة الأخطاء.
- ✅ 404 Handler.
- ✅ حل 8 تمارين عملية.
**تذكر:** التوجيه و Middleware هما ما يجعل تطبيقك **منظماً واحترافياً**.