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. أتقنه جيداً.