Artikel

APIs entwerfen, denen Clients vertrauen können: Ein praktischer Leitfaden vom Vertrag aus

APIs entwerfen, denen Clients vertrauen können: Ein praktischer Leitfaden vom Vertrag aus

Gute APIs machen den nächsten Schritt für Clients vorhersehbar. Ein Kursanmeldungs-Beispiel zeigt sichere Wiederholungen, verständliche Fehler und Änderungen am Vertrag.

10 Min. LesezeitSprache: DE DeutschKostenlos0 Claps0 Kommentare
Leseoptionen

Eine API ist ein Versprechen an andere Teams. Eine mobile App, eine Partnerintegration und eine spätere Version deines Frontends können von ihrem Verhalten abhängen. Dann ist die Umbenennung eines Feldes keine rein interne Änderung mehr. Deshalb kläre ich zunächst Verhalten, Fehlerfälle und sichere Wiederholungen, bevor ich einen Controller schreibe.

Als Beispiel dient eine API für Kursanmeldungen. Lernende sehen einen Kurs, beantragen einen Platz und erhalten eine stabile Anmelde-ID samt Status. Der Kurs kann voll sein, dieselbe Anfrage kann zweimal eintreffen, oder die Antwort geht verloren, nachdem der Server die Anmeldung gespeichert hat. Genau solche normalen Situationen entscheiden über die Qualität des Designs.

1. Beschreibe Client-Ablauf und Regeln

Ein angemeldeter Lernender ruft den Kurs ab, stellt einen Antrag und bekommt einen klaren Status. Nach einem Timeout muss ein erneuter Versuch ohne doppelte Anmeldung möglich sein. Die Regeln: höchstens eine aktive Anmeldung je Person und Kurs, Anmeldung nur im offenen Zeitraum und niemals mehr Plätze als Kapazität. Falls eine Zahlung nötig ist, legt gemeinsam fest, wann ein Platz reserviert und nach einem Fehlschlag freigegeben wird.

Zeige dem Client-Team Beispielanfrage und Antwort vor der Implementierung. Fehlende Felder und unklare Zustände lassen sich jetzt günstig korrigieren.

2. Benenne Ressourcen nach dem Ablauf

Anfrage Aufgabe Typischer Erfolg
GET /v1/courses/{courseId} Kurs lesen 200 OK
GET /v1/courses?cursor=...&limit=20 Kurse durchsuchen 200 OK
POST /v1/courses/{courseId}/enrollments Anmeldung beantragen 201 Created
GET /v1/enrollments/{enrollmentId} Status lesen 200 OK
DELETE /v1/enrollments/{enrollmentId} Erlaubte Stornierung 204 No Content

Wird der Vorgang erst später fertig, kann 202 Accepted mit einer Statusressource passender sein. Der Erfolgsstatus muss zum tatsächlich erreichten Zustand passen. GET dient dem Lesen, POST dem Erstellen oder Starten. Dass bestimmte HTTP-Methoden idempotent sind, macht nicht jeden POST automatisch sicher wiederholbar. Tabellen- und Controllernamen gehören nicht in den öffentlichen Vertrag.

3. Entwirf Anfrage und Antwort gemeinsam

POST /v1/courses/crs_42/enrollments HTTP/1.1
Authorization: Bearer <access-token>
Content-Type: application/json
Idempotency-Key: 9bfa06f8-3eb5-4d5d-85cd-43b02b56bf11

{"source":"course_page"}

Die Identität des Lernenden stammt aus der geprüften Authentifizierung und nicht aus einem frei änderbaren learnerId im Body. Eine mögliche Antwort:

HTTP/1.1 201 Created
Location: /v1/enrollments/enr_7f3
Content-Type: application/json

{"id":"enr_7f3","courseId":"crs_42","status":"confirmed","createdAt":"2026-09-29T10:30:00Z"}

Dokumentiere, ob IDs undurchsichtig sind, welche Statuswechsel erlaubt sind und welche Felder null sein können. Gib keine vollständige Datenbankzeile mit internen Notizen oder Daten anderer Lernender zurück. Listen sollten ein einheitliches Format wie data und page.nextCursor haben. Definiere Filter und Sortierung: Ohne stabile Reihenfolge überspringt oder verdoppelt Cursor-Paginierung Einträge.

4. Mache Fehler nutzbar

„Etwas ist schiefgelaufen“ hilft einem Client nicht. Unterscheide einen geschlossenen Kurs, eine abgelaufene Anmeldung, fehlende Rechte und einen Serverausfall. RFC 9457 Problem Details bietet ein gemeinsames Format:

{
  "type": "https://api.example.com/problems/enrollment-closed",
  "title": "Enrollment is closed",
  "status": 409,
  "detail": "This course stopped accepting enrollments."
}

In Produktion sollte type zu einer echten Problembeschreibung führen. Beschreibe auch Validierungsfehler pro Feld. SQL-Fehler, Stacktraces und Geheimnisse gehören nicht in die Antwort; sichere Logs und eine Korrelations-ID helfen dem Support. Lege eine einheitliche Politik für 401 (Authentifizierung), 403 (Berechtigung), 404 (Ressource), 409 (Zustandskonflikt) und 429 (Rate Limit) fest.

5. Plane Wiederholungen und konkurrierende Anfragen

Der Server kann die Anmeldung speichern, während die Antwort im Netz verloren geht. Mit einem Idempotency-Key schickt der Client eine eindeutige Kennung pro Versuch. Der Server speichert das Ergebnis und liefert es bei gleicher Kennung und gleichem Inhalt erneut. Dieselbe Kennung mit anderem Inhalt muss abgewiesen werden. Definiere Geltungsbereich, Aufbewahrungsdauer und Antwort. Für POST ist dies keine automatische HTTP-Garantie.

Sichere die fachliche Regel zusätzlich in der Datenbank ab. Wenn nur ein Platz übrig ist, dürfen zwei gleichzeitige Anfragen ihn nicht beide belegen. Nutze eine Transaktion oder sichere Reservierung und teste echte Parallelität. Webhooks und Queue-Jobs können ebenfalls mehrfach ausgeführt werden.

6. Trenne Authentifizierung und Autorisierung

Authentifizierung fragt: „Wer ruft an?“ Autorisierung fragt: „Darf diese Person auf genau diese Ressource zugreifen?“ Ein gültiges Token erlaubt nicht das Lesen fremder Anmeldungen. Erzwinge Regeln für Lernende, Lehrende und Administratoren serverseitig. Übernimm keine frei übermittelte Rolle aus dem Request-Body. Protokolliere keine Token; erkläre nach 429 das Warteverhalten und ob Limits pro Nutzer, Token oder Konto gelten.

7. Dokumentiere, teste und plane Änderungen

Beschreibe Pfade, Schemas, Sicherheit, Antworten und Fehlerbeispiele mit OpenAPI. Bitte einen Client-Entwickler, nur anhand dieses Dokuments zu integrieren. Seine Fragen zeigen Lücken. Teste 201, dieselbe Anfrage mit gleichem Schlüssel, einen geänderten Body mit altem Schlüssel, vollen Kurs, Zugriff auf fremde Anmeldungen, Konkurrenz um den letzten Platz und die Reihenfolge bei Paginierung.

Ein /v1-Pfad ist allein noch keine Versionsstrategie. Führe ein Änderungsprotokoll, kündige Abschaltungen an, miss die Nutzung alter Clients und veröffentliche Migrationsbeispiele. Ändere die Bedeutung eines bestehenden Feldes nicht stillschweigend. Bei einem neuen Status wie pending_payment brauchen ältere Clients einen sinnvollen Umgang mit unbekannten Werten.

Kurze Prüfung vor dem Release

Kann ein Client Erfolg und behandelbare Fehler erklären? Werden Rechte für die konkrete Ressource geprüft? Was passiert bei Wiederholung und Konkurrenz? Sind Filter, Sortierung und Paginierung klar? Entspricht OpenAPI dem laufenden System? Sind Fehler ohne Preisgabe sensibler Daten auffindbar? Gibt es einen Änderungsplan?

Eine API ist nicht zuverlässig, nur weil der einfache Fall einmal funktioniert. Vertrauen entsteht, wenn Clients nach Netzfehlern wiederaufnehmen, einen vollen Kurs behandeln und auch nach deinem nächsten Release weiterarbeiten können.

Quellen

Empfohlene Artikel

Shopify Entwickler werden: Ein praktischer Weg vom ersten Theme zur ersten App
EditorialDE
11 Min.Kostenlos

Shopify Entwickler werden: Ein praktischer Weg vom ersten Theme zur ersten App

Du möchtest Shopify Shops, Themes oder Apps entwickeln? Wähle einen Einstieg, schließe ein kleines Projekt ab und zeige deine Fähigkeiten an echten Beispielen.

Engineering-ArtikelPlattform-Leitfäden
0 Claps
Lesen
8 Claude Code Plugins, die Entwicklern 2026 den Alltag erleichtern
EditorialDE
5 Min.Kostenlos

8 Claude Code Plugins, die Entwicklern 2026 den Alltag erleichtern

Eine praktische Auswahl für Laravel und moderne Webprojekte, mit Beispielen und einem einfachen Einstieg.

Engineering-ArtikelKI-Leitfäden
0 Claps
Lesen
YOLO-Objekterkennung: Ein vollständiger Praxisleitfaden für Entwickler
EditorialDE
18 Min.Kostenlos

YOLO-Objekterkennung: Ein vollständiger Praxisleitfaden für Entwickler

Ein durchgängiger Entwicklerleitfaden zu YOLO: Grundlagen, Datenqualität, Training, Evaluation, Echtzeit-Inferenz, Produktion, Performance und Sicherheit.

Engineering-ArtikelKI-LeitfädenAIPythonVision
0 Claps
Lesen

Kommentare

0 Kommentare

Noch keine freigegebenen Kommentare sichtbar. Neue Antworten können moderiert werden.