מפתח
ברוכים הבאים!
פרויקט זה מיועד ללימוד Express.js למתחילים. הפרויקט כולל תיעוד מפורט בעברית ודוגמאות קוד מעשיות.
📋 תוכן עניינים
תיעוד (docs/)
- רקע והיסטוריה - מהו Express.js ומאיפה הוא הגיע
- יסודות - מושגים בסיסיים שחייבים לדעת
- סינטקס וצורת כתיבה - איך כותבים קוד Express נכון
- ניתוב (Routing) - ניהול נתיבים ובקשות HTTP
- תוכנת ביניים (Middleware) - פונקציות ביניים לעיבוד בקשות
דוגמאות קוד (examples/)
01-basic-server/- שרת בסיסי ראשון02-routing/- דוגמאות ניתוב03-middleware/- שימוש ב-middleware04-request-response/- טיפול בבקשות ותשובות05-static-files/- הגשת קבצים סטטיים06-error-handling/- טיפול בשגיאות07-template-engine/- שימוש בתבניות HTML
🔧 דרישות מקדימות
לפני שמתחילים, וודאו שמותקן אצלכם:
- Node.js (גרסה 14 ומעלה) - להורדה
- npm (מגיע עם Node.js)
- עורך קוד (מומלץ: VS Code)
בדיקת התקנה:
node --version # צריך להציג v14.0.0 או יותר
npm --version # צריך להציג 6.0.0 או יותר
🚀 התקנה והפעלה
שלב 1: התקנת התלויות
cd examples
npm install
שלב 2: הפעלת דוגמה
# הפעלת השרת הבסיסי
node 01-basic-server/server.js
שלב 3: בדיקה בדפדפן
פתחו את הדפדפן וגשו ל: http://localhost:3000
📚 סדר לימוד מומלץ
- התחילו מהרקע - הבינו מה זה Express ולמה הוא נוצר
- למדו את היסודות - הכירו את המושגים הבסיסיים
- תרגלו סינטקס - כתבו קוד בעצמכם
- נסו את הדוגמאות - הריצו כל דוגמה והבינו מה קורה
- בנו משהו משלכם - האפליקציה הראשונה שלכם!
💡 טיפים למתחילים
טיפ 1: התחילו תמיד מהשרת הבסיסי ביותר והוסיפו בהדרגה
טיפ 2: קראו את הודעות השגיאה - הן מאוד מועילות ב-Express
טיפ 3: השתמשו ב-
console.log()להבנת מה קורה בקוד
🔗 משאבים נוספים
בהצלחה בלימוד! 🎓
📖 רקע והיסטוריה של Express.js
מהו Express.js?
Express.js (או בקיצור Express) הוא Framework מינימליסטי וגמיש לפיתוח אפליקציות ווב ב-Node.js.
Express מספק סט כלים פשוט ועוצמתי לבניית: - שרתי Web (Web Servers) - ממשקי API (REST APIs) - אפליקציות Web מלאות (Full-stack applications)
🕐 היסטוריה
| שנה | אירוע |
|---|---|
| 2010 | TJ Holowaychuk יוצר את Express.js |
| 2014 | StrongLoop רוכשת את הפרויקט |
| 2015 | IBM רוכשת את StrongLoop |
| 2016 | Express עובר לקרן Node.js Foundation |
| היום | Express הוא ה-Framework הפופולרי ביותר ל-Node.js |
מי יצר את Express?
TJ Holowaychuk - מפתח פורה שיצר גם את: - Mocha (testing framework) - Jade/Pug (template engine) - Koa (framework מתקדם יותר)
🌟 למה Express?
יתרונות עיקריים
1. מינימליסטי ופשוט
// ALL כל מה שצריך בשביל שרת:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('שלום עולם!');
});
app.listen(3000);
2. גמישות מלאה
- אין כללים נוקשים - אתה מחליט את המבנה
- אפשר להוסיף רק מה שצריך
- עובד עם כל מסד נתונים
3. קהילה ענקית
- מעל 64,000 כוכבים ב-GitHub
- אלפי חבילות middleware זמינות
- תיעוד מעולה ודוגמאות רבות
4. ביצועים מצוינים
- קל משקל - לא מכיל קוד מיותר
- מהיר מאוד - מבוסס על Node.js
- סקיילביליות טובה
5. למידה קלה
- עקומת למידה קצרה
- מתאים למתחילים
- מעבר חלק מ-JavaScript רגיל
⚖️ השוואה לפריימוורקים אחרים
| תכונה | Express | Koa | Fastify | NestJS |
|---|---|---|---|---|
| קלות שימוש | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| ביצועים | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| גמישות | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| תיעוד | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| קהילה | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
Express vs. Koa
- Koa נוצר על ידי אותו יוצר (TJ)
- Koa יותר מודרני (async/await מובנה)
- Express יותר פופולרי ויש לו יותר middleware
Express vs. Fastify
- Fastify מהיר יותר בביצועים
- Express יותר בוגר ויציב
- Fastify דורש למידה נוספת
Express vs. NestJS
- NestJS מבוסס על Express
- NestJS מוסיף מבנה ו-TypeScript
- Express יותר גמיש ופשוט
🤔 מתי להשתמש ב-Express?
✅ כן - מתאים עבור:
- APIs פשוטים עד בינוניים
- אפליקציות Web קלות
- פרויקטים של למידה
- MVPs ופרוטוטייפים
- מיקרו-שירותים
❌ שקלו חלופות עבור:
- אפליקציות Enterprise גדולות - NestJS
- דרישות ביצועים קיצוניות - Fastify
- Full-stack עם SSR - Next.js
- Real-time אינטנסיבי - Socket.io (אפשר בשילוב Express)
🔧 דרישות להפעלת Express
Node.js
Express דורש Node.js להפעלה. Node.js הוא סביבת הרצה של JavaScript מחוץ לדפדפן.
# Node version check
node --version
# גרסה מינימלית: 14.0.0
# מומלץ: 18.0.0 ומעלה (LTS)
npm
מנהל החבילות של Node.js (מגיע עם Node.js).
# install express
npm install express
📊 סטטיסטיקות (2024)
- הורדות שבועיות: ~30 מיליון
- GitHub Stars: ~64,000
- תורמים: ~300
- חבילות תלויות: אלפים
Express הוא ה-Framework הפופולרי ביותר ל-Node.js ואחד הפופולריים ביותר בכלל!
🎯 סיכום
Express.js הוא הבחירה המושלמת למתחילים כי:
- פשוט ללמוד - מעט קוד לתוצאות גדולות
- מתועד היטב - קל למצוא עזרה
- גמיש - מתאים לכל סוג פרויקט
- פופולרי - דרוש בשוק העבודה
- בסיס טוב - מאפשר מעבר קל לפריימוורקים אחרים
🎯 יסודות Express.js
מושגים בסיסיים
לפני שמתחילים לכתוב קוד, חשוב להכיר את המושגים הבסיסיים:
🌐 מה זה שרת Web?
שרת Web הוא תוכנה שמחכה לבקשות מלקוחות (דפדפנים, אפליקציות) ומחזירה תשובות.
[לקוח/דפדפן] ──בקשה──► [שרת Express] ──תשובה──► [לקוח/דפדפן]
│ │ │
│ GET /users │ │
│ ──────────────────► │ │
│ │ (מעבד את הבקשה) │
│ │ │
│ [{user1}, {user2}] │ │
│ ◄─────────────────────────────────────────────── │
📦 Application Object (app)
ה-Application Object הוא הלב של כל אפליקציית Express.
const express = require('express');
const app = express(); // ← זהו ה-Application Object
מה אפשר לעשות עם app?
| פעולה | תיאור | דוגמה |
|---|---|---|
| הגדרת Routes | קביעת נתיבים | app.get('/path', handler) |
| הוספת Middleware | פונקציות ביניים | app.use(middleware) |
| הגדרות | קונפיגורציה | app.set('view engine', 'ejs') |
| הפעלת שרת | האזנה לפורט | app.listen(3000) |
📨 Request Object (req)
אובייקט ה-Request מכיל את כל המידע על הבקשה שהתקבלה מהלקוח.
app.get('/users/:id', (req, res) => {
console.log(req.method); // GET
console.log(req.path); // /users/123
console.log(req.params.id); // 123
console.log(req.query); // { sort: 'name' } (מ-URL: ?sort=name)
console.log(req.body); // גוף הבקשה (ב-POST)
console.log(req.headers); // כותרות HTTP
});
תכונות חשובות של req:
| תכונה | תיאור | דוגמה |
|---|---|---|
req.method |
סוג הבקשה | 'GET', 'POST' |
req.path |
הנתיב | '/users/123' |
req.params |
פרמטרים מהנתיב | { id: '123' } |
req.query |
Query string | { page: '1' } |
req.body |
גוף הבקשה | { name: 'John' } |
req.headers |
כותרות HTTP | { 'content-type': '...' } |
req.cookies |
עוגיות | { session: 'abc' } |
📤 Response Object (res)
אובייקט ה-Response משמש לשליחת תשובה ללקוח.
app.get('/', (req, res) => {
// שליחת טקסט
res.send('שלום עולם!');
// או שליחת JSON
res.json({ message: 'הצלחה!' });
// או שליחת קובץ HTML
res.sendFile('/path/to/file.html');
});
מתודות חשובות של res:
| מתודה | תיאור | דוגמה |
|---|---|---|
res.send() |
שליחת תגובה כללית | res.send('Hello') |
res.json() |
שליחת JSON | res.json({ ok: true }) |
res.status() |
קביעת קוד סטטוס | res.status(404) |
res.redirect() |
הפניה לכתובת אחרת | res.redirect('/login') |
res.render() |
רנדור תבנית | res.render('home') |
res.sendFile() |
שליחת קובץ | res.sendFile('/path') |
res.download() |
הורדת קובץ | res.download('/file.pdf') |
🛤️ Routing (ניתוב)
Routing הוא הגדרת איך האפליקציה תגיב לבקשות בנתיבים שונים.
מבנה בסיסי:
app.METHOD(PATH, HANDLER);
- METHOD - סוג בקשת HTTP (get, post, put, delete)
- PATH - הנתיב בכתובת
- HANDLER - פונקציה שמטפלת בבקשה
דוגמאות:
// Request GET לדף הבית
app.get('/', (req, res) => {
res.send('דף הבית');
});
// Request GET עם פרמטר
app.get('/users/:id', (req, res) => {
res.send(`משתמש מספר ${req.params.id}`);
});
// בקשת POST ליצירת משאב חדש
app.post('/users', (req, res) => {
res.json({ message: 'משתמש נוצר!' });
});
// בקשת PUT לעדכון
app.put('/users/:id', (req, res) => {
res.json({ message: 'משתמש עודכן!' });
});
// בקשת DELETE למחיקה
app.delete('/users/:id', (req, res) => {
res.json({ message: 'משתמש נמחק!' });
});
🔗 HTTP Methods
Express תומך בכל מתודות ה-HTTP:
| מתודה | שימוש | דוגמה |
|---|---|---|
| GET | קבלת מידע | קבלת רשימת משתמשים |
| POST | יצירת משאב חדש | יצירת משתמש חדש |
| PUT | עדכון מלא | החלפת כל פרטי המשתמש |
| PATCH | עדכון חלקי | עדכון השם בלבד |
| DELETE | מחיקה | מחיקת משתמש |
// GET - קבלת כל המשתמשים
app.get('/users', (req, res) => {
res.json(users);
});
// POST - יצירת משתמש
app.post('/users', (req, res) => {
const newUser = req.body;
users.push(newUser);
res.status(201).json(newUser);
});
// PUT - עדכון מלא
app.put('/users/:id', (req, res) => {
// החלפת המשתמש במידע החדש
});
// PATCH - עדכון חלקי
app.patch('/users/:id', (req, res) => {
// עדכון שדות ספציפיים
});
// DELETE - מחיקה
app.delete('/users/:id', (req, res) => {
// מחיקת המשתמש
});
⚡ Middleware
Middleware הן פונקציות שרצות בין קבלת הבקשה לשליחת התשובה.
[בקשה] → [Middleware 1] → [Middleware 2] → [Route Handler] → [תשובה]
צורת Middleware בסיסית:
const myMiddleware = (req, res, next) => {
// עשה משהו
console.log('בקשה התקבלה:', req.method, req.path);
// המשך ל-middleware הבא
next();
};
// שימוש ב-middleware
app.use(myMiddleware);
סוגי Middleware:
1. Application-level
// רץ על כל הבקשות
app.use((req, res, next) => {
console.log('Time:', Date.now());
next();
});
2. Router-level
const router = express.Router();
router.use((req, res, next) => {
// רק לנתיבים של הראוטר הזה
next();
});
3. Built-in Middleware
// פרסור JSON
app.use(express.json());
// פרסור URL-encoded
app.use(express.urlencoded({ extended: true }));
// קבצים סטטיים
app.use(express.static('public'));
4. Third-party Middleware
const cors = require('cors');
const morgan = require('morgan');
app.use(cors()); // אפשור CORS
app.use(morgan('dev')); // לוגים
🔄 שרשרת Middleware
Middleware רצים בסדר שבו הם מוגדרים:
const express = require('express');
const app = express();
// Middleware 1 - רץ ראשון
app.use((req, res, next) => {
console.log('1. Middleware ראשון');
next();
});
// Middleware 2 - רץ שני
app.use((req, res, next) => {
console.log('2. Middleware שני');
next();
});
// Route Handler - רץ אחרון
app.get('/', (req, res) => {
console.log('3. Route Handler');
res.send('סיום!');
});
// Output בקונסול:
// 1. Middleware ראשון
// 2. Middleware שני
// 3. Route Handler
🎓 סיכום היסודות
| מושג | תיאור |
|---|---|
| app | האובייקט הראשי של האפליקציה |
| req | מידע על הבקשה |
| res | שליחת תשובה ללקוח |
| Routing | הגדרת נתיבים ופעולות |
| Middleware | פונקציות ביניים לעיבוד |
| next() | מעבר ל-middleware הבא |
✍️ סינטקס וצורת כתיבה ב-Express.js
מבנה בסיסי של אפליקציית Express
כל אפליקציית Express מתחילה באותו מבנה:
// First
// ==============================================
// 1. ייבוא התלויות (Imports)
// ==============================================
const express = require('express');
// ==============================================
// 2. יצירת האפליקציה
// ==============================================
const app = express();
// ==============================================
// 3. הגדרות (Configuration)
// ==============================================
const PORT = 3000;
// ==============================================
// 4. Middleware גלובלי
// ==============================================
app.use(express.json());
// ==============================================
// 5. הגדרת Routes
// ==============================================
app.get('/', (req, res) => {
res.send('שלום עולם!');
});
// ==============================================
// 6. הפעלת השרת
// ==============================================
app.listen(PORT, () => {
console.log(`השרת רץ בפורט ${PORT}`);
});
📝 תבניות כתיבה נפוצות
1. הגדרת Route בסיסי
// Template: app.METHOD(PATH, HANDLER)
// הצורה הכי נפוצה - Arrow Function
app.get('/users', (req, res) => {
res.json({ users: [] });
});
// אפשר גם עם function רגיל
app.get('/users', function(req, res) {
res.json({ users: [] });
});
2. Route עם פרמטרים
// One פרמטר
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
res.send(`משתמש: ${userId}`);
});
// מספר פרמטרים
app.get('/users/:userId/posts/:postId', (req, res) => {
const { userId, postId } = req.params;
res.json({ userId, postId });
});
// פרמטר אופציונלי (עם ?)
app.get('/users/:id?', (req, res) => {
if (req.params.id) {
res.send(`משתמש ספציפי: ${req.params.id}`);
} else {
res.send('כל המשתמשים');
}
});
3. שימוש ב-Query String
// URL: /search?q=express&page=1
app.get('/search', (req, res) => {
const { q, page } = req.query;
res.json({
searchTerm: q, // 'express'
currentPage: page // '1'
});
});
4. קבלת נתונים מ-Body
// Must use middleware לפרסור JSON
app.use(express.json());
app.post('/users', (req, res) => {
const { name, email } = req.body;
// יצירת משתמש חדש
const newUser = {
id: Date.now(),
name,
email
};
res.status(201).json(newUser);
});
🎨 סגנונות כתיבה
סגנון 1: Inline Handlers (מתאים לפרויקטים קטנים)
// כל הלוגיקה ישירות ב-route
app.get('/users', (req, res) => {
const users = [
{ id: 1, name: 'יוסי' },
{ id: 2, name: 'דני' }
];
res.json(users);
});
סגנון 2: פונקציות נפרדות (Controllers)
// הפרדה של הלוגיקה לפונקציות
const getUsers = (req, res) => {
res.json({ users: [] });
};
const getUserById = (req, res) => {
res.json({ user: { id: req.params.id } });
};
const createUser = (req, res) => {
res.status(201).json({ user: req.body });
};
// רישום ה-routes
app.get('/users', getUsers);
app.get('/users/:id', getUserById);
app.post('/users', createUser);
סגנון 3: Route Chaining
// שרשור routes לאותו נתיב
app.route('/users')
.get((req, res) => {
res.json({ action: 'Get all users' });
})
.post((req, res) => {
res.json({ action: 'Create user' });
});
app.route('/users/:id')
.get((req, res) => {
res.json({ action: 'Get user by ID' });
})
.put((req, res) => {
res.json({ action: 'Update user' });
})
.delete((req, res) => {
res.json({ action: 'Delete user' });
});
📦 שליחת סוגי תשובות שונים
טקסט רגיל
app.get('/text', (req, res) => {
res.send('זהו טקסט רגיל');
});
JSON
app.get('/json', (req, res) => {
res.json({
message: 'הצלחה',
data: { id: 1, name: 'Test' }
});
});
HTML
app.get('/html', (req, res) => {
res.send('<h1>כותרת HTML</h1><p>פסקה</p>');
});
קובץ
app.get('/file', (req, res) => {
res.sendFile('/path/to/file.pdf');
});
הורדת קובץ
app.get('/download', (req, res) => {
res.download('/path/to/file.pdf', 'document.pdf');
});
הפניה (Redirect)
app.get('/old-page', (req, res) => {
res.redirect('/new-page');
});
// עם קוד סטטוס ספציפי
app.get('/moved', (req, res) => {
res.redirect(301, '/new-location');
});
📊 קודי סטטוס HTTP
הגדרת קוד סטטוס לפני התשובה:
// הצלחה
res.status(200).json({ message: 'OK' });
// נוצר בהצלחה
res.status(201).json({ message: 'Created' });
// אין תוכן להחזיר
res.status(204).send();
// בקשה שגויה
res.status(400).json({ error: 'Bad Request' });
// לא מורשה
res.status(401).json({ error: 'Unauthorized' });
// אסור
res.status(403).json({ error: 'Forbidden' });
// לא נמצא
res.status(404).json({ error: 'Not Found' });
// שגיאת שרת
res.status(500).json({ error: 'Internal Server Error' });
קודים נפוצים:
| קוד | משמעות | שימוש |
|---|---|---|
| 200 | OK | בקשה הצליחה |
| 201 | Created | משאב נוצר |
| 204 | No Content | הצלחה ללא תוכן |
| 400 | Bad Request | נתונים שגויים |
| 401 | Unauthorized | נדרשת הזדהות |
| 403 | Forbidden | אין הרשאה |
| 404 | Not Found | לא נמצא |
| 500 | Server Error | שגיאת שרת |
🔧 הגדרות (app.set)
// Set view engine
app.set('view engine', 'ejs');
// Set views directory
app.set('views', './views');
// הגדרת פורט
app.set('port', process.env.PORT || 3000);
// קריאת הגדרה
const port = app.get('port');
📁 מבנה תיקיות מומלץ
פרויקט קטן:
project/
├── server.js # קובץ ראשי
├── package.json
└── public/ # קבצים סטטיים
├── css/
├── js/
└── images/
פרויקט בינוני-גדול:
project/
├── src/
│ ├── app.js # הגדרת האפליקציה
│ ├── server.js # הפעלת השרת
│ ├── routes/ # הגדרת routes
│ │ ├── index.js
│ │ ├── users.js
│ │ └── products.js
│ ├── controllers/ # לוגיקה עסקית
│ │ ├── userController.js
│ │ └── productController.js
│ ├── middleware/ # middleware מותאם
│ │ ├── auth.js
│ │ └── validation.js
│ └── config/ # קבצי הגדרות
│ └── database.js
├── public/ # קבצים סטטיים
├── views/ # תבניות HTML
├── package.json
└── .env # משתני סביבה
✅ Best Practices (שיטות עבודה מומלצות)
1. השתמש ב-const
// ✅ Good practice
const express = require('express');
const app = express();
// ❌ Bad practice
var express = require('express');
2. טפל בשגיאות
// ✅ טוב
app.get('/users/:id', async (req, res) => {
try {
const user = await findUser(req.params.id);
res.json(user);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
3. השתמש ב-async/await
// ✅ Modern and clean
app.get('/data', async (req, res) => {
const data = await fetchData();
res.json(data);
});
// ❌ פחות קריא
app.get('/data', (req, res) => {
fetchData()
.then(data => res.json(data))
.catch(err => res.status(500).json(err));
});
4. הפרד לוגיקה לקבצים
// routes/users.js
const express = require('express');
const router = express.Router();
router.get('/', getUsers);
router.post('/', createUser);
module.exports = router;
// app.js
const userRoutes = require('./routes/users');
app.use('/users', userRoutes);
5. השתמש במשתני סביבה
// ✅ Good
const PORT = process.env.PORT || 3000;
// ❌ Bad
const PORT = 3000; // קשיח
🎯 סיכום - תבנית מלאה
// ===== server.js =====
const express = require('express');
const app = express();
// === Middleware ===
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static('public'));
// === Routes ===
app.get('/', (req, res) => {
res.json({ message: 'ברוכים הבאים!' });
});
app.get('/api/users', (req, res) => {
res.json({ users: [] });
});
app.post('/api/users', (req, res) => {
const { name, email } = req.body;
res.status(201).json({ id: 1, name, email });
});
// === Error Handler ===
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'שגיאה בשרת' });
});
// === Start Server ===
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`🚀 השרת רץ: http://localhost:${PORT}`);
});
🛤️ ניתוב (Routing) ב-Express.js
מהו Routing?
Routing הוא התהליך שבו האפליקציה מחליטה איך להגיב לבקשות בנתיבים שונים.
📋 מבנה בסיסי
app.METHOD(PATH, HANDLER);
| חלק | תיאור | דוגמה |
|---|---|---|
| METHOD | מתודת HTTP | get, post, put, delete |
| PATH | הנתיב ב-URL | '/', '/users' |
| HANDLER | הפונקציה שמטפלת | (req, res) => {} |
🔧 HTTP Methods
// GET - קבלת מידע
app.get('/users', (req, res) => {
res.json([{ id: 1, name: 'יוסי' }]);
});
// POST - יצירת משאב חדש
app.post('/users', (req, res) => {
res.status(201).json({ user: req.body });
});
// PUT - עדכון מלא
app.put('/users/:id', (req, res) => {
res.json({ updated: true });
});
// DELETE - מחיקה
app.delete('/users/:id', (req, res) => {
res.status(204).send();
});
🎯 Route Parameters
// One parameter
app.get('/users/:id', (req, res) => {
res.json({ userId: req.params.id });
});
// Multiple parameters
app.get('/users/:userId/posts/:postId', (req, res) => {
const { userId, postId } = req.params;
res.json({ userId, postId });
});
❓ Query Strings
// URL: /search?q=express&page=1
app.get('/search', (req, res) => {
const { q, page } = req.query;
res.json({ searchTerm: q, page });
});
📦 Express Router
// routes/users.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => res.json({ users: [] }));
router.get('/:id', (req, res) => res.json({ user: req.params.id }));
router.post('/', (req, res) => res.status(201).json(req.body));
module.exports = router;
// app.js
const usersRouter = require('./routes/users');
app.use('/users', usersRouter);
🔗 Route Chaining
app.route('/users')
.get((req, res) => res.json({ action: 'list' }))
.post((req, res) => res.json({ action: 'create' }));
⚡ Middleware ב-Express.js
מהו Middleware?
Middleware הן פונקציות שרצות בין קבלת הבקשה לשליחת התשובה.
[בקשה] → [Middleware 1] → [Middleware 2] → [Route] → [תשובה]
📝 מבנה בסיסי
const myMiddleware = (req, res, next) => {
// עשה משהו
console.log('בקשה:', req.method, req.path);
// המשך הלאה
next();
};
app.use(myMiddleware);
🔧 סוגי Middleware
1. Application-level
// Runs on all requests
app.use((req, res, next) => {
console.log('Time:', Date.now());
next();
});
// רץ רק על נתיב מסוים
app.use('/api', (req, res, next) => {
console.log('API request');
next();
});
2. Built-in Middleware
// Parse JSON
app.use(express.json());
// Parse URL-encoded
app.use(express.urlencoded({ extended: true }));
// קבצים סטטיים
app.use(express.static('public'));
3. Third-party Middleware
const cors = require('cors');
const morgan = require('morgan');
app.use(cors()); // אפשור CORS
app.use(morgan('dev')); // לוגים
🔗 סדר ביצוע
app.use((req, res, next) => {
console.log('1. ראשון');
next();
});
app.use((req, res, next) => {
console.log('2. שני');
next();
});
app.get('/', (req, res) => {
console.log('3. Route');
res.send('סיום');
});
// Output: 1, 2, 3
🛡️ Middleware לאימות
const authMiddleware = (req, res, next) => {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: 'לא מורשה' });
}
// אימות הטוקן...
next();
};
// שימוש על routes ספציפיים
app.get('/protected', authMiddleware, (req, res) => {
res.json({ secret: 'data' });
});
❌ Error Handling Middleware
// Must be at the end!
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'שגיאה בשרת' });
});