Express.js الأساسيات — Node.js و Express
أساسيات Express.js
Node يستطيع إنشاء خادم بوحدة http المدمجة، لكن Express يجعل التوجيه وقراءة البيانات والاستجابة أبسط بكثير. وهو أشهر إطار خلفي في Node.
أبسط خادم
const express = require("express");
const app = express();
app.use(express.json()); // قراءة JSON من جسم الطلب إلى req.body
app.get("/", (req, res) => {
res.send("مرحباً من Express");
});
const PORT = process.env.PORT || 3000; // منصات الاستضافة تحدد المنفذ
app.listen(PORT, () => console.log(`http://localhost:${PORT}`));npm install express
node --watch server.jsالمسار = طريقة + مسار + معالج
const express = require("express");
const app = express();
app.use(express.json());
app.get("/api/books", (req, res) => res.json([])); // قراءة
app.post("/api/books", (req, res) => res.status(201).json(req.body)); // إنشاء
app.put("/api/books/:id", (req, res) => res.json({ id: req.params.id }));
app.delete("/api/books/:id", (req, res) => res.status(204).end());مصادر البيانات في الطلب
| المصدر | مثال | في الكود |
|---|---|---|
| معاملات المسار | /api/books/42 | req.params.id ← "42" (نص دائماً) |
| سلسلة الاستعلام | /api/books?genre=novel | req.query.genre |
| الجسم (JSON) | POST بجسم | req.body (يحتاج express.json()) |
| الترويسات | Authorization: Bearer ... | req.get("authorization") |
⚠️ req.params.id نص: "42" === 42 خاطئ. حوّل وتحقق: Number(req.params.id) مع فحص Number.isInteger.
الاستجابة
| الدالة | الاستخدام |
|---|---|
| res.json(obj) | JSON مع الترويسة الصحيحة |
| res.status(201).json(obj) | رمز حالة + JSON |
| res.status(204).end() | نجاح بلا محتوى (بعد الحذف) |
| res.send(text) | نص أو HTML |
أرسل استجابة واحدة لكل طلب: استدعاء res.json مرتين يعطي خطأ "Cannot set headers after they are sent". استخدم return res... عند الخروج المبكر.
الملفات الثابتة
app.use(express.static("public")) يقدّم ملفات مجلد public (HTML و CSS والصور) مباشرة.
Express 5
الإصدار 5 (المستقر منذ 2024) يلتقط أخطاء الدوال async تلقائياً ويمررها لمعالج الأخطاء — في الإصدار 4 كان ذلك يحتاج غلافاً يدوياً (ستراه في درس معالجة الأخطاء).
تمرين
ابنِ API لقائمة كتب في الذاكرة: جلب الكل، جلب واحد بالمعرّف (404 إن لم يوجد، 400 إن لم يكن رقماً)، إضافة (201 مع التحقق من وجود العنوان)، وحذف (204). جرّبه بـ curl أو Thunder Client.
const express = require('express');
const app = express();
// Middleware لقراءة JSON
app.use(express.json());
// بيانات وهمية
let users = [
{ id: 1, name: 'أحمد', email: 'ahmed@example.com' },
{ id: 2, name: 'سارة', email: 'sara@example.com' },
];
// GET - جلب كل المستخدمين
app.get('/api/users', (req, res) => {
res.json(users);
});
// GET - جلب مستخدم واحد
app.get('/api/users/: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);
});
// POST - إضافة مستخدم
app.post('/api/users', (req, res) => {
const user = {
id: users.length + 1,
name: req.body.name,
email: req.body.email,
};
users.push(user);
res.status(201).json(user);
});
// DELETE - حذف مستخدم
app.delete('/api/users/:id', (req, res) => {
users = users.filter(u => u.id !== parseInt(req.params.id));
res.json({ message: 'تم الحذف' });
});
app.listen(3000, () => {
console.log('السيرفر يعمل على port 3000');
});اختبر فهمك