Was macht Express & Fastify?
Regeln
- Organisiere Routen nach Domänen:
routes/users.ts, routes/orders.ts – ein Router pro Ressource.
- Validiere alle Eingaben mit Zod: Parse
req.body, req.params, req.query vor der Verarbeitung.
- Zentrale Fehlerbehandlung: Catch-All-Middleware (Express) oder
setErrorHandler (Fastify).
- Rückgabe eines konsistenten Fehlerformats:
{ error: { code: string, message: string, details?: unknown } }.
- TypeScript: Typisiere Request/Response mit Generika –
Request<Params, ResBody, ReqBody, Query>.
- Middleware-Reihenfolge: CORS, Body-Parser, Authentifizierung, Ratenbegrenzung, Routen, Fehlerbehandler.
- Verwende asynchrone Route-Handler – umschließe sie mit Fehlerfang oder verwende
express-async-errors.
- Fastify: Nutze das Plugin-System, um Routen und Dekorateure zu kapseln –
fastify.register().
- Fastify-Schemas: Definiere JSON Schema oder verwende
@fastify/type-provider-zod für Validierung + Serialisierung.
- Health-Check:
GET /health – gib 200 mit DB/Redis-Konnektivitätsstatus zurück.
- Graceful Shutdown: Höre auf SIGTERM, stoppe die Annahme neuer Verbindungen, beende laufende Anfragen.
Muster
import { Router } from "express";
import { z } from "zod";
const router = Router();
const CreateUserSchema = z.object({ email: z.string().email(), name: z.string().min(1) });
router.post("/users", async (req, res, next) => {
try {
const body = CreateUserSchema.parse(req.body);
const user = await createUser(body);
res.status(201).json(user);
} catch (err) { next(err); }
});
import Fastify from "fastify";
import { serializerCompiler, validatorCompiler, ZodTypeProvider } from "fastify-type-provider-zod";
const app = Fastify().withTypeProvider<ZodTypeProvider>();
app.setValidatorCompiler(validatorCompiler);
app.setSerializerCompiler(serializerCompiler);
app.post("/users", { schema: { body: CreateUserSchema } }, async (req) => {
return createUser(req.body);
});
Vermeiden
- Geschäftslogik in Route-Handlern zu platzieren – extrahiere sie in die Service-/Domänenschicht.
- Asynchrone Fehlerbehandlung in Express zu vergessen – unbehandelte Promise-Ablehnungen lassen den Prozess abstürzen.
- Alle Routen in einer Datei zu importieren – verwende
router.use() oder Fastify-Plugins für Modularität.
- Eingabevalidierung zu überspringen, weil "das Frontend validiert" – validiere immer serverseitig.