מפתח

ברוכים הבאים!

פרויקט זה מיועד ללימוד Express.js למתחילים. הפרויקט כולל תיעוד מפורט בעברית ודוגמאות קוד מעשיות.


📋 תוכן עניינים

תיעוד (docs/)

  1. רקע והיסטוריה - מהו Express.js ומאיפה הוא הגיע
  2. יסודות - מושגים בסיסיים שחייבים לדעת
  3. סינטקס וצורת כתיבה - איך כותבים קוד Express נכון
  4. ניתוב (Routing) - ניהול נתיבים ובקשות HTTP
  5. תוכנת ביניים (Middleware) - פונקציות ביניים לעיבוד בקשות

דוגמאות קוד (examples/)

  1. 01-basic-server/ - שרת בסיסי ראשון
  2. 02-routing/ - דוגמאות ניתוב
  3. 03-middleware/ - שימוש ב-middleware
  4. 04-request-response/ - טיפול בבקשות ותשובות
  5. 05-static-files/ - הגשת קבצים סטטיים
  6. 06-error-handling/ - טיפול בשגיאות
  7. 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


📚 סדר לימוד מומלץ

  1. התחילו מהרקע - הבינו מה זה Express ולמה הוא נוצר
  2. למדו את היסודות - הכירו את המושגים הבסיסיים
  3. תרגלו סינטקס - כתבו קוד בעצמכם
  4. נסו את הדוגמאות - הריצו כל דוגמה והבינו מה קורה
  5. בנו משהו משלכם - האפליקציה הראשונה שלכם!

💡 טיפים למתחילים

טיפ 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 הוא הבחירה המושלמת למתחילים כי:

  1. פשוט ללמוד - מעט קוד לתוצאות גדולות
  2. מתועד היטב - קל למצוא עזרה
  3. גמיש - מתאים לכל סוג פרויקט
  4. פופולרי - דרוש בשוק העבודה
  5. בסיס טוב - מאפשר מעבר קל לפריימוורקים אחרים

המשך ליסודות ←

🎯 יסודות 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 →

⚡ 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: 'שגיאה בשרת' });
});

← חזרה לניתוב | חזרה לראשי