Zum Inhalt springen

Programmierung & Entwicklung

REST-APIs entwickeln lernen: sauber und robust

Lerne REST-APIs sauber und robust zu entwickeln: HTTP-Methoden, Ressourcen, Statuscodes, JSON, Authentifizierung, Versionierung und OpenAPI-Doku.

15. Juli 2024 7 Min. Lesezeit

KI-generiert

Eine REST-API ist schnell gebaut, aber schwer sauber zu halten. Ein paar falsche Entscheidungen am Anfang, und du schleppst sie über Jahre mit. Wenn du die grundlegenden Prinzipien verstehst, kannst du mit jedem Framework und in jeder Sprache stabile, gut wartbare APIs entwickeln.

Ressourcen statt Aktionen denken

Der wichtigste Perspektivwechsel: Du modellierst Ressourcen, nicht Methoden.

Statt dir zu überlegen, welche Funktionen dein Backend hat, denkst du in Dingen deiner Domäne:

  • Nutzer
  • Bestellungen
  • Artikel
  • Rechnungen
  • Kommentare

Diese Dinge bekommen URLs. Typische Beispiele:

  • GET /users
  • GET /users/42
  • POST /users
  • GET /orders/123/items
  • DELETE /orders/123

Vermeide in Pfaden Verben wie „createUser“, „getUserById“ oder „doLogin“. Die Aktion steckt in der HTTP-Methode, nicht in der URL. Schlechte Beispiele:

  • POST /createUser
  • GET /getUserById?id=42
  • POST /doOrder

Besser:

  • POST /users
  • GET /users/42
  • POST /orders

Ressourcen benennst du konsistent in der Mehrzahl: users, orders, invoices. Unterressourcen bilden Beziehungen ab:

  • GET /users/42/orders
  • GET /orders/123/items

HTTP-Methoden sinnvoll nutzen

HTTP bringt schon alles mit, um CRUD-Operationen auszudrücken. Nutze das, statt alles mit POST zu erschlagen:

  • GET: Ressource lesen, keine Seiteneffekte
  • POST: Ressource erstellen oder serverseitige Aktion auslösen
  • PUT: Ressource vollständig ersetzen
  • PATCH: Ressource teilweise aktualisieren
  • DELETE: Ressource löschen

Typische Zuordnung:

AktionMethodeBeispiel
Liste von Ressourcen holenGETGET /users
Einzelne Ressource holenGETGET /users/42
Neue Ressource anlegenPOSTPOST /users
Ressource komplett ändernPUTPUT /users/42
Ressource teilweise ändernPATCHPATCH /users/42
Ressource löschenDELETEDELETE /users/42

Ein paar Details, die oft falsch laufen:

  • GET darf keine Daten verändern. Kein Login, kein „Mark as read“, keine Bestellungen auslösen.
  • PUT ist idempotent: Mehrfaches Senden derselben Anfrage führt zum selben Ergebnis.
  • PATCH ist für Teilupdates. Definiere klar, wie dein Patch-Format aussieht, zum Beispiel JSON Merge Patch oder JSON Patch.

Statuscodes: Sag klar, was passiert ist

Viele APIs antworten nur mit 200 OK oder 500 Internal Server Error. Das ist verschenktes Potenzial. Statuscodes sind eine sehr günstige Form von Dokumentation.

Die wichtigsten Kategorien:

  • 2xx: Erfolg
  • 3xx: Umleitungen
  • 4xx: Fehler beim Client
  • 5xx: Fehler auf Serverseite

Praktisch relevant sind vor allem:

  • 200 OK: Alles in Ordnung, Antwort enthält Daten
  • 201 Created: Ressource erfolgreich angelegt, Location-Header mit neuer URL
  • 204 No Content: Erfolg ohne Antwortkörper, z. B. nach DELETE
  • 400 Bad Request: Anfrage formal ungültig oder nicht verständlich
  • 401 Unauthorized: Authentifizierung fehlt oder ist ungültig
  • 403 Forbidden: Authentifiziert, aber keine Berechtigung
  • 404 Not Found: Ressource existiert nicht (oder soll versteckt werden)
  • 409 Conflict: Konflikt mit aktuellem Zustand, z. B. beim parallelen Update
  • 422 Unprocessable Entity: Inhalt formal korrekt, aber fachlich nicht gültig
  • 500 Internal Server Error: Unerwarteter Fehler im Backend

Zusätzlich zum Statuscode solltest du im JSON-Body strukturierte Fehlermeldungen liefern, z. B.:

{
 "error": "validation_failed",
 "message": "Email ist ungültig",
 "details": {
 "email": "Keine gültige E-Mail-Adresse"
 }
}

Der genaue Aufbau ist dir überlassen, aber bleib konsistent über alle Endpunkte hinweg.

JSON: Klar, stabil, vorhersehbar

JSON ist de facto Standard für REST-APIs. Ein paar Grundregeln helfen dir, saubere Strukturen zu bauen:

  • Verwende konsistente Benennung, zum Beispiel snake_case oder camelCase, aber nicht beides gemischt.
  • Nutze stabile Feldnamen, vermeide spätere Umbenennungen.
  • Liefere nur Felder, die du auch dokumentierst.
  • Verwende sinnvolle Datentypen: keine Zahlen als Strings, keine Datumsangaben ohne Format.

Typischer Response für eine Ressource:

{
 "id": 42,
 "name": "Max Mustermann",
 "email": "max@example.com",
 "createdAt": "2024-07-01T12:34:56Z",
 "roles": ["user", "admin"]
}

Für Listen:

{
 "items": [
 { "id": 1, "name": "..." },
 { "id": 2, "name": "..." }
 ],
 "total": 23,
 "limit": 10,
 "offset": 0
}

So kannst du Pagination sauber abbilden, ohne später deine Struktur zu brechen.

Authentifizierung und Autorisierung: Tokens statt Sessions

REST-APIs sind in der Regel zustandslos. Der Server speichert keinen Anmeldestatus, jede Anfrage muss für sich authentifizierbar sein.

Gängige Praxis:

  • Authentifizierung über HTTP-Header
  • Token-basierte Verfahren, typischerweise Bearer-Token
  • HTTPS ist Pflicht, sonst sind alle Tokens wertlos

Beispiel:

GET /users/me
Authorization: Bearer eyJhbGciOiJI...

Wichtige Prinzipien:

  • Trenne Authentifizierung (Wer bist du?) von Autorisierung (Was darfst du?).
  • Gib möglichst wenig über Berechtigungen preis. Verwende 403 Forbidden, wenn jemand zwar existiert, aber nicht zugreifen darf.
  • Setze sinnvolle Token-Lebensdauern und Refresh-Mechanismen, wenn du mit JWT oder ähnlichen Verfahren arbeitest.

Für viele Szenarien ist OAuth 2.0 bzw. OpenID Connect eine gute Basis, insbesondere im Zusammenspiel mit Frontends oder Drittanbietern. Für interne APIs in einem Münchner Firmennetz reicht manchmal auch ein einfaches statisches Token oder ein zentrales Auth-Gateway.

Versionierung: Änderungen kontrolliert einführen

APIs leben. Anforderungen ändern sich, Felder kommen hinzu oder fallen weg. Versionierung hilft dir, bestehende Clients nicht zu brechen.

Drei verbreitete Ansätze:

  1. Version in der URL Beispiel: /v1/users, /v2/users Vorteil: sehr sichtbar, einfach zu handhaben. Nachteil: Du musst Pfade duplizieren, alte Versionen pflegen.

  2. Version im Header Beispiel: Accept: application/vnd.example.v1+json Vorteil: Pfade bleiben sauber, du kannst granularer versionieren. Nachteil: Weniger sichtbar, etwas komplexer zu erklären.

  3. Nur additive Änderungen ohne „harte“ Versionierung Beispiel: Du fügst nur neue Felder hinzu, entfernst aber nichts. Vorteil: Wenig Overhead. Nachteil: Irgendwann schleppt die API Altlasten mit.

Pragmatischer Ansatz:

  • Plane von Anfang an mit einer ersten Version, z. B. /api/v1/.
  • Betrachte die API als Vertrag. Breaking Changes brauchen eine neue Version.
  • Markiere alte Versionen klar als veraltet und plane ein Enddatum.

Konsistentes Design: Regeln aufschreiben

Eine REST-API ist dann angenehm zu benutzen, wenn sie vorhersehbar ist. Das erreichst du mit einfachen Design-Regeln, die ihr im Team schriftlich festhaltet:

  • Einheitliche Pfadstruktur und Benennung
  • Immer dieselben Statuscodes für dieselben Situationen
  • Gleiches Fehlerformat für alle Endpunkte
  • Gleiche Pagination-Strategie
  • Gleiche Authentifizierungsmechanismen

Beispiele für solche Konventionen:

  • Ressourcen immer in der Mehrzahl: users, nicht user.
  • IDs sind immer numerisch oder immer UUIDs, nicht gemischt.
  • Zeitangaben immer in ISO 8601 und in UTC.
  • Boolean-Felder heißen isActive, isAdmin usw.

Diese Regeln sind wichtiger als das konkrete Framework. Ob du in München mit Spring Boot, .NET, Node.js oder Django arbeitest, spielt dann keine große Rolle mehr.

Dokumentation mit OpenAPI

Eine gute REST-API braucht eine gute Dokumentation. Sonst verbringen alle zu viel Zeit mit Rückfragen und Debugging.

OpenAPI (früher Swagger) ist der etablierte Standard, um HTTP-APIs zu beschreiben. Du definierst:

  • Pfade und Methoden
  • Request-Parameter und Bodies
  • Response-Strukturen
  • Statuscodes
  • Sicherheitsmechanismen (z. B. Bearer-Token)

Vorteile einer sauberen OpenAPI-Beschreibung:

  • Automatisch generierte, klickbare Doku
  • Client-SDKs können generiert werden
  • Tests können strukturiert aufgebaut werden
  • Änderungen werden sichtbar und diskutierbar

Achte darauf, dass deine Doku zur Realität passt. Am besten generierst du sie direkt aus dem Code oder überprüfst sie automatisiert in der CI-Pipeline.

Praktische Tipps für robuste REST-APIs

Zum Abschluss ein paar erprobte Praktiken, die dir in Projekten viel Ärger ersparen:

  • Nutze HTTP-Caching dort, wo es sinnvoll ist, zum Beispiel mit ETag und Last-Modified.
  • Begrenze Ergebnislisten (Pagination) und setze sinnvolle Standardlimits, um den Server zu schützen.
  • Logge Anfragen und Antworten strukturiert, aber ohne vertrauliche Daten mitzuschreiben.
  • Halte die API so einfach wie möglich, aber nicht einfacher. Lieber wenige klar definierte Endpunkte als einen Wildwuchs.
  • Teste nicht nur die Businesslogik, sondern auch das API-Verhalten: Statuscodes, Fehlerfälle, Authentifizierung.

Wenn du diese Prinzipien verinnerlichst, kannst du dich im nächsten Schritt auf konkrete Implementierungen in deinem bevorzugten Stack konzentrieren. Aktuelle Termine und passende Kurse findest du bei cmt.de.

REST-APIs sauber zu entwickeln ist kein Hexenwerk. Mit einem klaren Ressourcenmodell, konsequenter Nutzung von HTTP und einer gepflegten Dokumentation legst du das Fundament für langlebige Schnittstellen, die auch in ein paar Jahren noch verständlich und erweiterbar sind.

Nächster Schritt

Passenden Kurs zu Programmierung finden.

Feste Termine, erfahrene Trainer, Präsenz in München und Durchführungsgarantie. Buchen kannst du direkt auf cmt.de.