Appearance
Kapitel 10: Express Framework Einführung
🎯 Lernziele
In diesem Kapitel lernen Sie:
- ✅ Was Express.js ist und warum man es verwendet
- ✅ Express installieren und Projekt initialisieren
- ✅ Express-Server erstellen und starten
- ✅ Routing konfigurieren (GET, POST, etc.)
- ✅ Middleware-Konzept verstehen
- ✅ Statische Ressourcen bereitstellen
- ✅ Express vs. native
http-Modul
10.1 Was ist Express?
📖 Einfache Definition
Express.js ist ein minmalistisches Web-Framework für Node.js, das die Erstellung von Webservern und APIs drastisch vereinfacht.
🎨 Visuelle Erklärung
Ohne Express (Native http):
┌─────────────────────────────────┐
│ Viele if-else für Routing │
│ Manuelle Header-Setzung │
│ Komplexe Middleware-Logik │
│ (Viel Boilerplate-Code!) │
└─────────────────────────────────┘
Mit Express:
┌─────────────────────────────────┐
│ Einfache Routing-API │
│ Automatische Header │
│ Einfache Middleware │
│ (Weniger Code, mehr Leistung!) │
└─────────────────────────────────┘💡 Vorteile von Express
| Vorteil | Beschreibung |
|---|---|
| Einfach | Weniger Code für gleiche Funktionalität |
| Flexibel | Unzählige Middleware verfügbar |
| Performant | Minimaler Overhead |
| Beliebt | Über 20 Millionen Downloads/Woche |
🌟 Bekannte Unternehmen
- Uber - Ride-sharing API
- PayPal - Zahlungsabwicklung
- Myntra - E-Commerce-Plattform
10.2 Installation & Initialisierung
📦 Express installieren
bash
# Neues Projekt erstellen
mkdir mein-express-projekt
cd mein-express-projekt
# npm-Projekt initialisieren
npm init -y
# Express installieren
npm install express📄 package.json nach Installation
json
{
"name": "mein-express-projekt",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
},
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^3.0.2"
}
}10.3 Kernfunktionen
🚀 Server erstellen und starten
index.js:
javascript
const express = require('express');
const app = express();
const port = 3000;
// Route definieren
app.get('/', (req, res) => {
res.send('🎉 Hallo von Express-Server!');
});
// Server starten
app.listen(port, () => {
console.log(`🚀 Express-Server läuft auf http://localhost:${port}`);
});▶️ Server starten
bash
# Produktion
npm start
# Entwicklung (mit Nodemon)
npm run dev🗺️ Routing konfigurieren
Einfache Routen
javascript
const express = require('express');
const app = express();
// GET-Route
app.get('/', (req, res) => {
res.send('🏠 Startseite');
});
// POST-Route
app.post('/api/users', (req, res) => {
res.send('✅ Nutzer erstellt');
});
// PUT-Route
app.put('/api/users/:id', (req, res) => {
res.send(`🔄 Nutzer ${req.params.id} aktualisiert`);
});
// DELETE-Route
app.delete('/api/users/:id', (req, res) => {
res.send(`🗑️ Nutzer ${req.params.id} gelöscht`);
});
// Alle Methoden (catch-all)
app.all('/test', (req, res) => {
res.send(`Methode: ${req.method}`);
});
app.listen(3000);Route mit Pfadparametern
javascript
// Route mit Parameter: /api/users/123
app.get('/api/users/:id', (req, res) => {
const userId = req.params.id;
res.send(`Nutzer-ID: ${userId}`);
});
// Mehrere Parameter: /api/users/123/posts/456
app.get('/api/users/:userId/posts/:postId', (req, res) => {
const { userId, postId } = req.params;
res.send(`Nutzer: ${userId}, Post: ${postId}`);
});🧩 Middleware (Wichtig!)
MiddleWare = Funktionen, die zwischen Request und Response ausgeführt werden.
Visuelle Erklärung
Client-Anfrage (Request)
↓
┌──────────────────────┐
│ Middleware 1 │ → loggingMiddleware()
└──────────────────────┘
↓
┌──────────────────────┐
│ Middleware 2 │ → authMiddleware()
└──────────────────────┘
↓
┌──────────────────────┐
│ Route-Handler │ → app.get('/', ...)
└──────────────────────┘
↓
Antwort (Response)Eigene Middleware erstellen
javascript
const express = require('express');
const app = express();
// Eigene Middleware-Funktion
function loggingMiddleware(req, res, next) {
console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
// WICHTIG: next() aufrufen, um zur nächsten Middleware/Route zu gelangen!
next();
}
// Middleware global anwenden (für ALLE Routen)
app.use(loggingMiddleware);
// Route
app.get('/', (req, res) => {
res.send('Startseite (mit Logging)');
});
app.listen(3000);Ausgabe:
2024-01-15T10:30:00.000Z - GET /
2024-01-15T10:30:05.000Z - GET /aboutVordefinierte Middleware
javascript
const express = require('express');
const app = express();
// JSON-Body parsen (für POST/PUT)
app.use(express.json());
// URL-encoded Body parsen
app.use(express.urlencoded({ extended: true }));
// Statische Dateien servieren
app.use(express.static('public'));
// CORS aktivieren
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
next();
});
app.listen(3000);📁 Statische Ressourcen bereitstellen
javascript
const express = require('express');
const app = express();
// Statische Dateien aus "public"-Ordner servieren
app.use(express.static('public'));
// Beispiel:
// public/
// ├── index.html
// ├── style.css
// └── script.js
// Aufruf:
// http://localhost:3000/ → public/index.html
// http://localhost:3000/style.css → public/style.css
app.listen(3000, () => {
console.log('📂 Statische Dateien aus ./public werden serviert');
});Mehrere Statische Ordner
javascript
// Mehrere Ordner für statische Dateien
app.use(express.static('public'));
app.use(express.static('uploads'));
app.use('/bilder', express.static('bilder'));
// → http://localhost:3000/bilder/logo.png10.4 Praxisbeispiele
🛠️ Fallstudie 1: API-Server mit Express erstellen
server.js:
javascript
const express = require('express');
const app = express();
const port = 3000;
// Middleware
app.use(express.json()); // JSON-Body parsen
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
// "Datenbank" (Array)
let users = [
{ id: 1, name: 'Max', email: 'max@example.com' },
{ id: 2, name: 'Anna', email: 'anna@example.com' }
];
// ROUTES
// 1. Alle Nutzer abrufen (GET)
app.get('/api/users', (req, res) => {
res.json({ success: true, data: users });
});
// 2. Einzelnen Nutzer abrufen (GET)
app.get('/api/users/:id', (req, res) => {
const id = parseInt(req.params.id);
const user = users.find(u => u.id === id);
if (!user) {
return res.status(404).json({ success: false, error: 'Nutzer nicht gefunden' });
}
res.json({ success: true, data: user });
});
// 3. Nutzer erstellen (POST)
app.post('/api/users', (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({ success: false, error: 'Name und Email erforderlich' });
}
const newUser = {
id: users.length + 1,
name,
email
};
users.push(newUser);
res.status(201).json({ success: true, data: newUser });
});
// 4. Nutzer aktualisieren (PUT)
app.put('/api/users/:id', (req, res) => {
const id = parseInt(req.params.id);
const { name, email } = req.body;
const userIndex = users.findIndex(u => u.id === id);
if (userIndex === -1) {
return res.status(404).json({ success: false, error: 'Nutzer nicht gefunden' });
}
users[userIndex] = { id, name, email };
res.json({ success: true, data: users[userIndex] });
});
// 5. Nutzer löschen (DELETE)
app.delete('/api/users/:id', (req, res) => {
const id = parseInt(req.params.id);
const userIndex = users.findIndex(u => u.id === id);
if (userIndex === -1) {
return res.status(404).json({ success: false, error: 'Nutzer nicht gefunden' });
}
users.splice(userIndex, 1);
res.json({ success: true, message: 'Nutzer gelöscht' });
});
// Server starten
app.listen(port, () => {
console.log(`🚀 API-Server läuft auf http://localhost:${port}`);
console.log('\nVerfügbare Endpunkte:');
console.log(' GET /api/users');
console.log(' GET /api/users/:id');
console.log(' POST /api/users');
console.log(' PUT /api/users/:id');
console.log(' DELETE /api/users/:id');
});Testen mit curl
bash
# Alle Nutzer abrufen
curl http://localhost:3000/api/users
# Einzelnen Nutzer abrufen
curl http://localhost:3000/api/users/1
# Nutzer erstellen
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"name":"Clara","email":"clara@example.com"}'
# Nutzer aktualisieren
curl -X PUT http://localhost:3000/api/users/1 \
-H "Content-Type: application/json" \
-d '{"name":"Max Mustermann","email":"max.neu@example.com"}'
# Nutzer löschen
curl -X DELETE http://localhost:3000/api/users/2📂 Fallstudie 2: Statische Webseite mit Express
Projektstruktur:
meine-webseite/
├── server.js
├── public/
│ ├── index.html
│ ├── about.html
│ ├── css/
│ │ └── style.css
│ └── js/
│ └── script.jsserver.js:
javascript
const express = require('express');
const path = require('path');
const app = express();
const port = 3000;
// Statische Dateien servieren
app.use(express.static(path.join(__dirname, 'public')));
// Fallback: Wenn Route nicht gefunden → 404
app.use((req, res) => {
res.status(404).sendFile(path.join(__dirname, 'public', '404.html'));
});
app.listen(port, () => {
console.log(`🚀 Webserver läuft auf http://localhost:${port}`);
console.log('📂 Statische Dateien aus ./public werden serviert');
});public/index.html:
html
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Meine Webseite</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<h1>🏠 Willkommen!</h1>
<p>Diese Webseite wird mit Express serviert.</p>
<a href="/about.html">Über uns</a>
<script src="/js/script.js"></script>
</body>
</html>10.5 Vergleich
| Aspekt | Native http | Express |
|---|---|---|
| Routing | Manuell mit if/else | app.get(), app.post(), etc. |
| Middleware | Schwer zu implementieren | Einfach mit app.use() |
| Body-Parsing | Manuell (req.on('data')) | Automatisch (express.json()) |
| Statische Dateien | Manuell mit fs.createReadStream() | express.static() |
| Code-Menge | Viel | Weniger |
📝 Code-Vergleich
Mit nativem http:
javascript
const http = require('http');
const fs = require('fs');
const url = require('url');
const server = http.createServer((req, res) => {
const parsedUrl = url.parse(req.url);
if (req.method === 'GET' && parsedUrl.pathname === '/') {
fs.readFile('index.html', (err, data) => {
if (err) {
res.writeHead(500);
res.end('Serverfehler');
} else {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(data);
}
});
} else if (req.method === 'POST' && parsedUrl.pathname === '/api/data') {
let body = '';
req.on('data', chunk => body += chunk);
req.on('end', () => {
const data = JSON.parse(body);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ success: true, data }));
});
} else {
res.writeHead(404);
res.end('404 - Nicht gefunden');
}
});
server.listen(3000);Mit Express:
javascript
const express = require('express');
const app = express();
app.use(express.static('public'));
app.use(express.json());
app.get('/', (req, res) => {
res.sendFile('index.html', { root: '.' });
});
app.post('/api/data', (req, res) => {
res.json({ success: true, data: req.body });
});
app.use((req, res) => {
res.status(404).send('404 - Nicht gefunden');
});
app.listen(3000);Ergebnis: Express benötigt weniger Code und ist besser lesbar!
📝 Zusammenfassung
In diesem Kapitel haben Sie gelernt:
- ✅ Express ist ein minimalistisches Web-Framework für Node.js
- ✅ Express installieren (
npm install express) - ✅ Express-Server erstellen und konfigurieren
- ✅ Routing mit
app.get(),app.post(), etc. - ✅ Middleware-Konzept und
app.use() - ✅ Statische Dateien mit
express.static()servieren - ✅ Express vs. native
http(Express ist viel einfacher!)
🎯 Nächste Schritte
Im nächsten Kapitel werden wir:
- Grundlegende Praxisprojekte durchführen
- Log-Tool erstellen (FS-Modul)
- Statischen Webserver erstellen
- Einfache API-Schnittstellen entwickeln
📚 Weiterführende Ressourcen
🎉 Kapitel 10 abgeschlossen! Weiter zu Kapitel 11: Grundlegende Praxis
