Fast jede moderne Anwendung kommuniziert über eine API – ob Mobile-App, Single-Page-Application oder Microservice. Das weitverbreitetste Architekturmuster dafür ist REST. Wer Backend-Entwicklung betreibt oder Frontends baut, die mit einem Server sprechen, muss REST verstehen. Dieser Artikel erklärt die Grundlagen von REST-APIs klar und praxisnah – von HTTP-Methoden bis zur OpenAPI-Dokumentation.
Was ist eine API und was ist REST?
Eine API (Application Programming Interface) ist eine definierte Schnittstelle, über die zwei Systeme miteinander kommunizieren. Eine Web-API ist eine API, die über HTTP angesprochen wird – der Browser oder deine App sendet eine Anfrage, der Server antwortet mit Daten.
REST (Representational State Transfer) ist kein Protokoll, sondern ein Architekturstil, den Roy Fielding im Jahr 2000 in seiner Dissertation definiert hat. Eine API, die den REST-Prinzipien folgt, wird als RESTful API bezeichnet. REST ist heute der dominierende Standard für Web-APIs, weil er einfach, skalierbar und zustandslos ist.
Die REST-Constraints erklärt
REST definiert sechs Constraints. Die drei wichtigsten für den Alltag:
Stateless (Zustandslos)
Jede Anfrage an eine REST-API muss alle notwendigen Informationen enthalten – der Server speichert keinen Client-Zustand zwischen Anfragen. Das bedeutet: Kein Session-State auf dem Server. Authentifizierungsdaten (z.B. ein Token) müssen bei jeder Anfrage mitgeschickt werden. Das macht REST-APIs horizontal skalierbar – du kannst beliebig viele Server-Instanzen betreiben.
Uniform Interface (Einheitliche Schnittstelle)
REST-APIs arbeiten mit Ressourcen. Jede Ressource hat eine eindeutige URL (URI) und wird über standardisierte HTTP-Methoden manipuliert. Das macht APIs vorhersehbar und einfach zu verstehen – egal welche Programmiersprache dahintersteckt.
Resource-Based (Ressourcenorientiert)
In REST denkst du in Ressourcen (Substantive), nicht in Aktionen (Verben). Eine Ressource ist alles, was du benennen kannst: ein Nutzer, ein Produkt, ein Bestellvorgang. Die HTTP-Methode (GET, POST, etc.) bestimmt, was mit der Ressource passiert.
HTTP-Methoden richtig einsetzen
Die fünf wichtigsten HTTP-Methoden und ihre Bedeutung in REST:
- GET – Ressource(n) lesen. Keine Seiteneffekte, idempotent, cacheable. Beispiel:
GET /api/produkteoderGET /api/produkte/42 - POST – Neue Ressource erstellen. Nicht idempotent (mehrfaches Aufrufen erstellt mehrere Ressourcen). Beispiel:
POST /api/produkte - PUT – Ressource vollständig ersetzen (alle Felder). Idempotent. Beispiel:
PUT /api/produkte/42 - PATCH – Ressource teilweise aktualisieren (nur geänderte Felder). Beispiel:
PATCH /api/produkte/42 - DELETE – Ressource löschen. Idempotent. Beispiel:
DELETE /api/produkte/42
Idempotent bedeutet: Dieselbe Anfrage mehrfach ausgeführt hat denselben Effekt wie einmal. GET, PUT und DELETE sind idempotent – POST nicht.
HTTP-Statuscodes
Statuscodes teilen dem Client mit, ob die Anfrage erfolgreich war. Die wichtigsten Bereiche:
2xx – Erfolg
- 200 OK – Standardantwort für erfolgreiche GET, PUT, PATCH
- 201 Created – Ressource erfolgreich erstellt (nach POST)
- 204 No Content – Erfolgreich, keine Antwortdaten (nach DELETE)
3xx – Weiterleitungen
- 301 Moved Permanently – Ressource dauerhaft verschoben
- 304 Not Modified – Gecachter Inhalt ist noch aktuell
4xx – Client-Fehler
- 400 Bad Request – Ungültige Anfrage (z.B. fehlende Pflichtfelder)
- 401 Unauthorized – Authentifizierung erforderlich
- 403 Forbidden – Authentifiziert, aber keine Berechtigung
- 404 Not Found – Ressource existiert nicht
- 422 Unprocessable Entity – Validierungsfehler
- 429 Too Many Requests – Rate Limit überschritten
5xx – Server-Fehler
- 500 Internal Server Error – Allgemeiner Server-Fehler
- 503 Service Unavailable – Server überlastet oder in Wartung
URL-Design: Best Practices
Gutes URL-Design macht eine API intuitiv nutzbar. Die wichtigsten Regeln:
# Gut: Ressourcen im Plural, Kleinbuchstaben, Bindestriche
GET /api/v1/produkte
GET /api/v1/produkte/42
GET /api/v1/produkte/42/bewertungen
POST /api/v1/bestellungen
# Schlecht: Verben in der URL (REST-Antipattern!)
GET /api/getProdukte
POST /api/createBestellung
GET /api/produkt_liste
Verwende Substantive im Plural für Ressourcen. Verschachtelungen (/produkte/42/bewertungen) sind für direkte Beziehungen sinnvoll, aber begrenze die Tiefe auf maximal 2–3 Ebenen. Filter, Sortierung und Pagination gehören in den Query String:
GET /api/v1/produkte?kategorie=elektronik&sort=preis&order=asc&page=2&limit=20
Request- und Response-Format: JSON
Das Standard-Datenformat für REST-APIs ist JSON (JavaScript Object Notation). Setze immer den korrekten Content-Type-Header:
# Request
POST /api/v1/produkte
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
{
"name": "Laptop Pro 15",
"preis": 1299.99,
"kategorie": "elektronik",
"lagerbestand": 42
}
# Response (201 Created)
{
"data": {
"id": 123,
"name": "Laptop Pro 15",
"preis": 1299.99,
"kategorie": "elektronik",
"lagerbestand": 42,
"erstellt_am": "2026-06-12T10:30:00Z"
}
}
Wrapping der Antwort in ein data-Feld ist eine bewährte Konvention – sie lässt Raum für Metadaten wie Pagination-Informationen auf der gleichen Ebene.
Authentifizierung: Bearer Token, JWT und API-Keys
REST-APIs sind zustandslos – die Authentifizierung muss bei jeder Anfrage mitgeschickt werden.
Bearer Token / JWT
JWT (JSON Web Token) ist das verbreitetste Format für API-Tokens. Ein JWT enthält signierte Claims (z.B. User-ID, Rollen, Ablaufzeit) und wird im Authorization-Header mitgeschickt:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE3ODAwMDAwMDB9.abc123
Der Server validiert die Signatur des Tokens – ohne Datenbankabfrage, da alle Informationen im Token selbst stecken. JWTs haben ein Ablaufdatum (exp); kombiniere sie mit Refresh Tokens für langlebige Sessions.
API-Keys
Für Server-zu-Server-Kommunikation und einfachere Use-Cases sind API-Keys praktisch. Sie werden im Header (X-API-Key: dein-key) oder als Query-Parameter (?api_key=dein-key, weniger empfohlen) übergeben.
Versionierung
APIs ändern sich – breaking Changes erfordern eine neue Version. Die drei gängigsten Strategien:
- URL-Versioning:
/api/v1/,/api/v2/– einfachste und verbreitetste Methode - Header-Versioning:
Accept: application/vnd.api+json;version=2– sauberer, aber komplexer - Query-Parameter:
/api/produkte?version=2– selten, schlecht für Caching
Empfehlung: Starte mit URL-Versioning (/api/v1/). Es ist transparent, einfach zu debuggen und von jedem HTTP-Client problemlos nutzbar.
Dokumentation mit OpenAPI / Swagger
OpenAPI (früher Swagger) ist der Standard zur Beschreibung von REST-APIs in einer maschinenlesbaren YAML/JSON-Datei. Daraus generierst du automatisch interaktive Dokumentation, Client-SDKs und Validierungslogik.
openapi: 3.0.3
info:
title: Produkte API
version: 1.0.0
paths:
/api/v1/produkte:
get:
summary: Alle Produkte abrufen
parameters:
- name: kategorie
in: query
schema:
type: string
responses:
'200':
description: Produktliste
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Produkt'
Tools wie Swagger UI oder Redoc rendern daraus eine durchklickbare Dokumentation. Für Laravel gibt es das Paket darkaonline/l5-swagger, für Node.js/Express swagger-jsdoc und swagger-ui-express.
CORS und Rate Limiting
CORS (Cross-Origin Resource Sharing) ist ein Browser-Sicherheitsmechanismus. Wenn dein Frontend auf app.example.com läuft und deine API auf api.example.com, blockiert der Browser Anfragen ohne korrekte CORS-Header. Konfiguriere deinen Server so:
# Beispiel CORS-Header
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type
Rate Limiting schützt deine API vor Missbrauch und Überlastung. Begrenze Anfragen pro Client (IP oder API-Key) und gib Rate-Limit-Informationen in den Response-Headern zurück:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 1749729600
Praktisches Beispiel: REST-API mit Laravel
Laravel bietet mit seinen Resource Controllers eine elegante Struktur für REST-APIs:
// routes/api.php
Route::apiResource('produkte', ProduktController::class);
// Generiert automatisch:
// GET /api/produkte -> index()
// POST /api/produkte -> store()
// GET /api/produkte/{id} -> show()
// PUT /api/produkte/{id} -> update()
// DELETE /api/produkte/{id} -> destroy()
// app/Http/Controllers/ProduktController.php
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'preis' => 'required|numeric|min:0',
'kategorie' => 'required|string',
]);
$produkt = Produkt::create($validated);
return response()->json(['data' => $produkt], 201);
}
Für die Node.js-Seite lohnt sich ein Blick auf Node.js und npm. Für TypeScript-typisierte APIs ist TypeScript ein großer Gewinn.
Häufige Fragen
Was ist der Unterschied zwischen REST und GraphQL?
REST hat feste Endpoints pro Ressource – du bekommst immer die gleiche Datenstruktur zurück. GraphQL hat einen einzigen Endpoint und der Client spezifiziert exakt, welche Felder er braucht. GraphQL eignet sich besonders für komplexe, verschachtelte Datenmodelle und mobile Apps, die Datenvolumen sparen wollen. REST ist einfacher, besser gecacht und für die meisten Anwendungen ausreichend.
Soll ich PUT oder PATCH verwenden?
Verwende PUT, wenn du eine Ressource komplett ersetzen willst (alle Felder müssen mitgeschickt werden). Verwende PATCH, wenn du nur einzelne Felder aktualisierst. In der Praxis verwenden viele APIs PATCH für Update-Operationen, da es flexibler ist.
Wie sichere ich meine API gegen unbefugten Zugriff?
Nutze immer HTTPS (TLS) für die Transportverschlüsselung. Implementiere Authentifizierung (JWT oder API-Keys). Validiere alle Eingaben serverseitig. Setze Rate Limiting ein. Logge verdächtige Anfragen und implementiere Monitoring. Für öffentliche APIs lohnt sich OAuth 2.0 als Authentifizierungsframework.
Was ist der Unterschied zwischen 401 und 403?
401 Unauthorized bedeutet: Der Client ist nicht authentifiziert – er muss sich zuerst anmelden. 403 Forbidden bedeutet: Der Client ist authentifiziert, hat aber keine Berechtigung für diese Ressource. Der Unterschied ist wichtig für korrektes Client-Verhalten: Bei 401 soll der Client neu einloggen, bei 403 ist weiteres Einloggen sinnlos.
Wie versioniere ich eine API ohne bestehende Clients zu brechen?
Führe breaking Changes immer unter einer neuen Version ein (/api/v2/). Behalte die alte Version mindestens 6–12 Monate bei und kommuniziere das Deprecation-Datum klar in der Dokumentation und per Deprecation-Header. Additive Änderungen (neue Felder in der Response hinzufügen) sind keine breaking Changes und können in der bestehenden Version eingeführt werden.