Learn JavaScript logo
Navigation umschalten

Express.js lernen: Comprehensive Guide

Express ist das beliebteste Node.js Framework für Backend-Entwicklung. Diese Seite führt dich komplett von Anfänger zum Express-Profi.

Was ist Express.js?

Express ist ein minimalistisches und flexibles Node.js Web Framework:

  • Lightweight: Schnell zu lernen, schnell zu schreiben
  • Flexible: Wähle selbst Middleware, Patterns, Architecture
  • Powerful: Alles möglich (APIs, Web-Apps, Microservices, Real-time)
  • Popular: Industriestandard für Node.js Backend
  • Well-supported: Große Community, viele Ressourcen
  • Proven: Genutzt von Uber, Netflix, PayPal, IBM, etc.

Warum Express.js lernen?

  • ~80% der Node.js Backends nutzen Express
  • Easy Learning Curve: Schnell produktiv
  • Vielseitig: Nicht nur REST APIs
  • Große Ökosystem: Middleware für alles
  • Gehalt: 60.000–75.000 EUR für Backend Entwickler
  • Nachfrage: Ständig Backend-Entwickler gesucht

Wann ist Express die richtige Wahl?

Express ist gut für:

  • REST APIs (das Haupteinsatzgebiet)
  • Server-rendered Web Apps
  • Real-time Apps (mit Socket.io)
  • Microservices
  • Flexible Custom Solutions
  • MVP schnell bauen

Alternativen überwiegen für:

  • Monolithic Enterprise Monolithen → NestJS
  • serverless Funktionen → AWS Lambda
  • Extreme Performance Requirements → Fastify

Voraussetzungen

  • Gute JavaScript Grundlagen (wichtig!)
  • Node.js Basics: Installation, npm, Module
  • HTTP Grundlagen: Request/Response, Status Codes, Methods
  • Kommandozeile: Comfort mit Terminal/CLI
  • Asynchrones JavaScript: Promises, async/await

JavaScript für Anfänger - falls nötig Backend-Entwickler mit Node.js - empfohlen

Express Learning Path

Phase 1: Express Basics & HTTP (1 Woche)

Konzepte verstehen:

  • HTTP Requests und Responses
  • Status Codes (200, 404, 500, etc.)
  • HTTP Methods (GET, POST, PUT, DELETE, PATCH)
  • Headers und Body
  • URL Parameters und Query Strings
  • Cookies und Sessions

Express Setup:

npm init -y
npm install express

First Express Server:

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello World!');
});

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

Routing:

  • GET, POST, PUT, DELETE Routes
  • URL Parameters: /users/:id
  • Query Strings: ?name=John&age=30
  • Wildcard Routes: *

Praktische Übungen:

  • Hello World Server
  • Static File Server
  • Simple Routing
  • URL Parameter Parsing
  • Query String Parsing

Phase 2: Middleware verstehen (1 Woche)

Middleware Konzept:

  • Was ist Middleware?
  • Request → Middleware Pipeline → Response
  • next() Function
  • Built-in Middleware
  • Custom Middleware
  • Error Handling Middleware

Wichtige Built-in Middleware:

// JSON Body Parsing
app.use(express.json());

// URL-encoded Forms
app.use(express.urlencoded({ extended: true }));

// Static Files
app.use(express.static('public'));

// Logging Middleware
app.use((req, res, next) => {
  console.log(`${req.method} ${req.path}`);
  next();
});

Custom Middleware:

// Authentication Middleware
const requireAuth = (req, res, next) => {
  const token = req.headers.authorization;
  if (!token) {
    return res.status(401).send('Unauthorized');
  }
  req.user = verifyToken(token);
  next();
};

// Error Handling Middleware
app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).send('Internal Server Error');
});

Praktische Übungen:

  • Logging Middleware
  • Authentication Middleware
  • Error Handler
  • CORS Middleware
  • Request Timing Middleware

Phase 3: Routing & Request Handling (1–2 Wochen)

RESTful Conventions:

  • GET /resources → Liste aller
  • GET /resources/:id → Einzelnes
  • POST /resources → Neues erstellen
  • PUT /resources/:id → Vollständig updaten
  • PATCH /resources/:id → Teilweise updaten
  • DELETE /resources/:id → Löschen

Router Organization:

// routes/users.js
const express = require('express');
const router = express.Router();

router.get('/', getAllUsers);
router.get('/:id', getUserById);
router.post('/', createUser);
router.put('/:id', updateUser);
router.delete('/:id', deleteUser);

module.exports = router;

// app.js
const userRoutes = require('./routes/users');
app.use('/api/users', userRoutes);

Request Handling:

  • req.params (URL Parameter)
  • req.query (Query Strings)
  • req.body (POST/PUT Data)
  • req.headers (Headers)
  • res.send(), res.json(), res.status()
  • Error Responses

Validierung:

  • Input Validation
  • Error Responses
  • HTTP Status Codes korrekt nutzen

Praktische Projekte:

  • Simple REST API (Notes, Todos)
  • User Management API
  • Product Catalog API
  • Blog Post API

Phase 4: Database Integration (2–3 Wochen)

Populäre Datenbanken:

  • PostgreSQL: Relational, skalierbar
  • MongoDB: Document-based, flexibel
  • MySQL: Relational, widespread
  • SQLite: Lightweight, Development

ORMs und ODMs:

  • Sequelize: SQL ORM (PostgreSQL, MySQL, SQLite)
  • TypeORM: SQL ORM mit TypeScript Support
  • Prisma: Modern SQL ORM
  • Mongoose: MongoDB ODM

Praktisches Setup mit Sequelize:

const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('database', 'user', 'password', {
  host: 'localhost',
  dialect: 'postgres'
});

const User = sequelize.define('User', {
  name: DataTypes.STRING,
  email: DataTypes.STRING,
  age: DataTypes.INTEGER
});

sequelize.sync();

// Usage in Route
app.get('/users', async (req, res) => {
  const users = await User.findAll();
  res.json(users);
});

app.post('/users', async (req, res) => {
  const user = await User.create(req.body);
  res.json(user);
});

Praktische Übungen:

  • Database Setup
  • Model Definition
  • CRUD Operations
  • Relationships (One-to-Many, Many-to-Many)
  • Migrations
  • Seeding Test Data

Praktische Projekte:

  • Blog App mit Authors, Posts, Comments
  • E-Commerce Katalog
  • User Authentication System

Phase 5: Authentication & Authorization (2 Wochen)

Konzepte:

  • Authentication: Wer bist du?
  • Authorization: Was darfst du?
  • Sessions vs. Tokens
  • Password Security

Passwort Hashing:

const bcrypt = require('bcrypt');

// Hashing beim Registration
const hash = await bcrypt.hash(password, 10);

// Verification beim Login
const isValid = await bcrypt.compare(password, hash);

JWT (JSON Web Tokens):

const jwt = require('jsonwebtoken');

// Generate Token
const token = jwt.sign({ userId: user.id }, 'secret', { expiresIn: '7d' });

// Verify Token in Middleware
const verifyToken = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).send('Unauthorized');
  
  try {
    req.user = jwt.verify(token, 'secret');
    next();
  } catch {
    res.status(403).send('Invalid token');
  }
};

Sessions (mit express-session):

const session = require('express-session');

app.use(session({
  secret: 'your-secret',
  resave: false,
  saveUninitialized: false
}));

// Login
app.post('/login', (req, res) => {
  req.session.userId = user.id;
  res.send('Logged in!');
});

// Require Login
const requireLogin = (req, res, next) => {
  if (!req.session.userId) return res.status(401).send('Unauthorized');
  next();
};

Praktische Implementierung:

  • Registration Endpoint
  • Login Endpoint
  • Protected Routes
  • Token Refresh
  • Logout Handling
  • Role-based Access Control (RBAC)

Praktische Projekte:

  • Secure Note App
  • Private User Profiles
  • Role-based Admin Panel
  • Permission-based API

Phase 6: Error Handling & Logging (1–2 Wochen)

Error Handling Strategie:

  • Try-Catch für async Code
  • Error Middleware
  • Consistent Error Responses
  • Logging

Error Response Format:

app.use((err, req, res, next) => {
  console.error(err);
  res.status(err.status || 500).json({
    error: {
      message: err.message,
      status: err.status || 500,
      // In production: nicht den vollständigen Stack zeigen!
    }
  });
});

Logging Libraries:

  • Winston: Popular, flexible
  • Pino: High performance
  • Morgan: HTTP Request Logging
  • Bunyan: JSON Logging

Winston Beispiel:

const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' })
  ]
});

app.use((req, res, next) => {
  logger.info(`${req.method} ${req.path}`);
  next();
});

Praktische Übungen:

  • Global Error Handler
  • Logging Integration
  • Error Monitoring (Sentry)
  • Development vs. Production Error Responses

Phase 7: Advanced Features (2 Woeken)

File Upload:

const multer = require('multer');
const upload = multer({ dest: 'uploads/' });

app.post('/upload', upload.single('file'), (req, res) => {
  res.json({ filename: req.file.filename });
});

Rate Limiting & Security:

const rateLimit = require('express-rate-limit');
const helmet = require('helmet');

app.use(helmet()); // Security Headers
app.use(rateLimit({
  windowMs: 15 * 60 * 1000, // 15 min
  max: 100 // limit each IP to 100 requests per windowMs
}));

Email Sending:

const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  host: 'smtp.example.com',
  port: 587,
  auth: { user: 'email', pass: 'password' }
});

transporter.sendMail({
  from: 'sender@example.com',
  to: 'recipient@example.com',
  subject: 'Hello',
  text: 'Hello World!'
});

Pagination & Filtering:

app.get('/users', async (req, res) => {
  const page = req.query.page || 1;
  const limit = req.query.limit || 10;
  const offset = (page - 1) * limit;
  
  const users = await User.findAll({
    limit,
    offset,
    where: { role: req.query.role }
  });
  
  res.json(users);
});

Caching:

const redis = require('redis');
const client = redis.createClient();

app.get('/users/:id', async (req, res) => {
  const cached = await client.get(`user:${req.params.id}`);
  if (cached) return res.json(JSON.parse(cached));
  
  const user = await User.findByPk(req.params.id);
  client.set(`user:${req.params.id}`, JSON.stringify(user));
  res.json(user);
});

Phase 8: Testing (1–2 Wochen)

Unit Testing:

  • Jest oder Mocha + Chai
  • Service Logic testen
  • Database Mocking

Integration Testing:

const request = require('supertest');
const app = require('./app');

describe('User API', () => {
  it('GET /users sollte alle Users zurückgeben', async () => {
    const res = await request(app)
      .get('/users')
      .expect(200);
    
    expect(res.body).toBeInstanceOf(Array);
  });

  it('POST /users sollte neuen User erstellen', async () => {
    const res = await request(app)
      .post('/users')
      .send({ name: 'John', email: 'john@example.com' })
      .expect(201);
    
    expect(res.body).toHaveProperty('id');
  });
});

Praktische Tests:

  • Authentication Flow
  • Error Handling
  • Validation
  • Authorization

Phase 9: Deployment & DevOps (1–2 Wochen)

Deployment Platforms:

  • Heroku: Simple, für schnelle Deployments
  • AWS (EC2, Elastic Beanstalk)
  • DigitalOcean: Affordable VPS
  • Render.com, Railway: Modern Platform as a Service
  • Docker + Kubernetes: Enterprise

Environment Management:

# .env file
DATABASE_URL=postgres://...
JWT_SECRET=your-secret
NODE_ENV=production

Docker Setup:

FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]

CI/CD Integration:

  • GitHub Actions für Automated Testing & Deployment
  • Automated Versioning
  • Zero-downtime Deployments

Praktische Übungen:

  • Docker Container erstellen
  • Environment-basierte Konfiguration
  • CI/CD Pipeline Setup

Advanced Express Patterns

Custom Error Classes

class AppError extends Error {
  constructor(message, statusCode) {
    super(message);
    this.statusCode = statusCode;
  }
}

throw new AppError('Resource not found', 404);

Async Route Wrapper

const catchAsync = (fn) => (req, res, next) => {
  fn(req, res, next).catch(next);
};

app.get('/users/:id', catchAsync(async (req, res) => {
  const user = await User.findByPk(req.params.id);
  res.json(user);
}));

Dependency Injection

class UserController {
  constructor(userService) {
    this.userService = userService;
  }

  async getUser(req, res) {
    const user = await this.userService.getById(req.params.id);
    res.json(user);
  }
}

const userService = new UserService();
const userController = new UserController(userService);

Capstone Projekt – Production-ready API (3–4 Wochen)

Baue eine komplette REST API von Grund auf:

Beispiel-Projekt: E-Commerce API

Features:

  1. User Management

    • Registration & Login
    • User Profiles
    • Password Reset
  2. Product Management

    • Browse & Search
    • Filtering & Sorting
    • Product Details
    • Reviews & Ratings
  3. Shopping Cart

    • Add/Remove Items
    • Inventory Management
    • Price Calculation
  4. Orders

    • Order Placement
    • Payment Integration (Stripe)
    • Order Tracking
    • Email Notifications
  5. Admin Panel API

    • Inventory Management
    • Sales Analytics
    • User Management
    • Dispute Resolution
  6. Architecture

    • Modular Structure (routes, controllers, services)
    • Database Relationships
    • Comprehensive Validation
    • Error Handling
    • Logging
    • Testing (70%+ Coverage)
    • Security (Helmet, Rate Limiting, Input Validation)
    • Authentication & Authorization
    • Pagination & Filtering
    • Caching (Redis)
    • CI/CD Pipeline
    • Docker Deployment

Ablauf

  • Week 1: Setup, Database, User Management
  • Week 2: Product & Cart Features
  • Week 3: Orders, Payments, Notifications
  • Week 4: Testing, Optimization, Deployment

Express vs. Alternativen

Framework Komplexität Performance Ecosystem Use Case
Express Niedrig Gut Riesig Flexible APIs, Custom Apps
NestJS Hoch Gut Wachsend Enterprise, TypeScript
Fastify Niedrig Hervorragend Klein Ultra-Performance APIs
Koa Niedrig Gut Klein Modern, Middleware-first
Hapi Hoch Gut Mittel Enterprise, Plugins

Express ist beste Wahl für die meisten Fälle.

Learning-Ressourcen

Offizielle Dokumentation

  • Express Official Docs: expressjs.com
  • Node.js Documentation: nodejs.org

Online Kurse

  • The Complete Node.js Developer Course (Udemy)
  • Express.js & MongoDB REST API (Udemy)
  • Backend Development Bootcamp (FreeCodeCamp)
  • REST APIs mit Express (Pluralsight)

Freie Ressourcen

  • Express Docs Examples: expressjs.com/en/starter/examples.html
  • Node.js Best Practices: github.com/goldbergyoni/nodebestpractices
  • Dev.to Tutorials: dev.to (tag: express, node)

Bücher

  • "Web Development with Node and Express" – Ethan Brown
  • "Express in Action" – Evan Hahn
  • "Node.js Design Patterns" – Mario Casciaro

Häufig gestellte Fragen

Sollte ich Express oder NestJS lernen? Express zuerst. NestJS später für Enterprise. Express ist fundamentaler.

Welche Datenbank soll ich mit Express verwenden? PostgreSQL/MySQL für relationale Daten. MongoDB für flexible Schemas. Anfänger: SQLite.

Wie skaliert Express zu großen Apps? Gut. Viele große Apps nutzen Express. Mit guter Architektur ist Skalierung möglich.

Muss ich TypeScript mit Express verwenden? Nein, aber empfohlen für größere Projekte.

Wie lange brauche ich, um Express zu lernen? 4–6 Wochen für Grundlagen. 6–12 Monate für Production-ready Skills.

Kann ich mit Express ein Startup gründen? Absolut! Express ist perfekt für MVP und Skalierung.

Zusammenfassung

Express ist das Go-to Framework für Backend-Entwicklung mit Node.js. Mit seiner minimalistischen, aber flexiblen Architektur kannst du von einfachen APIs bis zu komplexen Microservices alles bauen.

Folge dem Lernpfad: Basics → Routing → Middleware → Database → Authentication → Error Handling → Advanced Features → Testing → Deployment. Nach diesem Pfad kannst du komplette Production-ready APIs architektieren und implementieren.

Express ist wert gelernt zu werden. Es ist zeitlos, vielseitig und die Tür zu einer großartigen Backend-Entwickler-Karriere.