Express.js

Node.js minimales Web-Framework - unopinioniert, middleware-basiert, der Industriestandard fuer Node-Backends

TL;DR

Eine Zeile: Express ist das minimale Web-Framework für Node.js - Server mit nur den Teilen bauen, die Sie brauchen.

Kernstärken:

  • Minimal und unopinionated - Sie entscheiden die Architektur
  • Middleware-Ökosystem - Tausende von Plugins
  • Industriestandard - das beliebteste Node.js-Framework
  • Express 5 - native Promise-Unterstützung, bessere Sicherheit

Core Concepts

Concept 1: Middleware

Alles in Express ist Middleware - Funktionen mit Zugriff auf Request, Response und next.

// Middleware läuft in Reihenfolge
app.use(express.json());      // 1. JSON parsen
app.use(logRequest);          // 2. Logging
app.get('/api', handler);     // 3. Route-Handler

function logRequest(req, res, next) {
  console.log(`${req.method} ${req.path}`);
  next();  // An nächste Middleware weiterleiten
}

Concept 2: Routing

Endpoints mit HTTP-Methoden definieren:

app.get('/users', getUsers);      // GET /users
app.post('/users', createUser);   // POST /users
app.put('/users/:id', updateUser); // PUT /users/123
app.delete('/users/:id', deleteUser);

Concept 3: Request & Response

app.get('/users/:id', (req, res) => {
  const id = req.params.id;       // URL-Parameter
  const sort = req.query.sort;    // Query-String ?sort=name
  const token = req.headers.authorization;

  res.status(200).json({ id, sort });
});

Quick Start

Create Project

mkdir my-app && cd my-app
npm init -y
npm install express

Create index.js

import express from 'express';
const app = express();

app.use(express.json());

app.get('/', (req, res) => {
  res.json({ message: 'Hallo Express!' });
});

app.listen(3000, () => {
  console.log('Server läuft auf http://localhost:3000');
});

Run

node index.js
# Öffne http://localhost:3000

Gotchas

Don’t forget next() in middleware

// ❌ Request hängt ewig
app.use((req, res, next) => {
  console.log('Logging...');
  // next() fehlt!
});

// ✅ Korrekt
app.use((req, res, next) => {
  console.log('Logging...');
  next();
});

Error handling needs 4 parameters

// Muss alle 4 Parameter haben, damit Express es erkennt
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ error: 'Etwas ist kaputt gegangen!' });
});

// Fehler mit next(err) auslösen
app.get('/fail', (req, res, next) => {
  next(new Error('Ups!'));
});

Route order matters

// ❌ Falsch - /users/me wird nie erreicht
app.get('/users/:id', (req, res) => ...);
app.get('/users/me', (req, res) => ...);  // Wird nie erreicht!

// ✅ Korrekt - spezifische Routen zuerst
app.get('/users/me', (req, res) => ...);
app.get('/users/:id', (req, res) => ...);

Async errors in Express 5+

// Express 5: Async-Fehler werden automatisch gefangen
app.get('/data', async (req, res) => {
  const data = await fetchData();  // Fehler werden gefangen!
  res.json(data);
});

// Express 4: Try-Catch oder Wrapper nötig
app.get('/data', async (req, res, next) => {
  try {
    const data = await fetchData();
    res.json(data);
  } catch (err) {
    next(err);
  }
});

When to Use

Am besten für:

  • REST APIs
  • Leichtgewichtige Server
  • Teams, die volle Kontrolle wollen
  • Projekte mit spezifischen Architektur-Anforderungen

Nicht ideal für:

  • Große Apps, die Struktur brauchen (NestJS verwenden)
  • Echtzeit-Apps (Fastify oder Hono verwenden)
  • TypeScript-first Projekte (NestJS verwenden)

Vergleich:

FeatureExpressFastifyNestJS
GeschwindigkeitMittelSchnellMittel
OpinionatedNeinNeinJa
TypeScriptAdd-onEingebautEingebaut
LernkurveEinfachEinfachMittel

Next Steps

Cheatsheet

PatternCode
GET Routeapp.get('/path', handler)
POST Routeapp.post('/path', handler)
Middlewareapp.use(middleware)
URL Parameterreq.params.id
Query Parameterreq.query.name
Bodyreq.body (braucht express.json())
JSON Antwortres.json({ data })
Statusres.status(404).json({})
Routerconst router = express.Router()
Statische Dateienapp.use(express.static('public'))