Zum Inhalt springen

Web-APIs im Detail — HTTP, REST und Statuscodes

Methoden, Ressourcen, Statuscodes und ein Vertrag, den andere nutzen können

Einleitung

Wenn ein Frontend, eine mobile App oder ein fremdes System Daten von deinem Backend abruft oder dort speichert, geschieht das über eine API. Im Web bauen die allermeisten APIs auf HTTP auf — demselben Protokoll, das der Browser zum Abrufen von Seiten nutzt. Verstehst du HTTP richtig, verstehst du das Fundament unter praktisch der gesamten Webkommunikation, nicht nur unter APIs.

HTTP — Anfrage und Antwort

HTTP ist darauf aufgebaut, dass ein Client eine Anfrage sendet und der Server eine Antwort schickt. Eine Anfrage hat eine Methode (was will ich tun), einen Pfad (woran will ich es tun), eventuelle Header (Metaangaben) und vielleicht einen Body mit Daten. Die Antwort hat einen Statuscode (ist es gut gegangen), Header und typischerweise einen Body mit dem Ergebnis — bei einer Web-API oft im JSON-Format. Jede Anfrage steht grundsätzlich für sich; der Server merkt sich nichts zwischen ihnen, sofern man das nicht bewusst mit z. B. einer Session oder einem Token einbaut.

Die Methoden verraten die Absicht

Die HTTP-Methoden (auch Verben genannt) sagen, was man will. Sie ihrer Bedeutung entsprechend zu verwenden, macht eine API vorhersehbar. Eine wichtige Eigenschaft ist, ob eine Methode sicher ist (verändert keine Daten) und idempotent (derselbe Aufruf wiederholt ergibt denselben Zustand) — das entscheidet, ob es unbedenklich ist, einen Aufruf zu wiederholen, der vielleicht nicht angekommen ist.

MethodeAbsichtÄndert Daten?
GETEine Ressource abrufenNein (sicher)
POSTEine neue Ressource anlegen oder eine Aktion auslösenJa
PUTEine Ressource vollständig ersetzenJa (idempotent)
PATCHEinen Teil einer Ressource aktualisierenJa
DELETEEine Ressource löschenJa (idempotent)

REST — Ressourcen statt Aktionen

REST ist ein verbreiteter Stil für Web-APIs. Die Kernidee ist, in Ressourcen zu denken — Dingen, die eine Adresse haben — statt in Aktionen. Statt eines Endpunkts wie 'erstelleBenutzer' hat man eine Ressource 'Benutzer', auf die man die Methoden anwendet: die Liste holen, einen neuen anlegen, einen bestimmten holen, ihn aktualisieren, ihn löschen. Die Adressen werden nach den Dingen benannt (Substantive, gern im Plural), und die Methode bestimmt die Aktion. Das ergibt ein API, das leicht zu erraten und einheitlich zu benutzen ist.

Statuscodes — die Antwort in einer einzigen Zahl

Der Statuscode in der Antwort sagt kurz, wie es gelaufen ist. Sie sind in Serien gruppiert, und es sind die Gruppen, die du vor allem kennen musst: Die 2er-Serie bedeutet Erfolg, die 3er-Serie bedeutet Umleitung, die 4er-Serie bedeutet einen Fehler beim Client (du hast etwas Falsches gesendet), und die 5er-Serie bedeutet einen Fehler auf dem Server. Den richtigen Code zu verwenden ist Teil des Vertrags — ein Client muss korrekt reagieren können, ohne zu raten.

  • 01Die 2er-Serie: es hat geklappt — z. B. angelegt oder abgerufen
  • 02Die 3er-Serie: der Klient muss woandershin
  • 03Die 4er-Serie: der Client hat etwas falsch gemacht — z. B. ungültige Eingabe, nicht eingeloggt, kein Zugriff, existiert nicht
  • 045er-Serie: Der Server ist fehlgeschlagen — es ist nicht die Schuld des Clients

Versionierung und Vertrag

Wenn andere auf deiner API aufbauen, ist sie ein Vertrag: Änderst du sie abrupt, zerbrichst du ihre Systeme. Deshalb versioniert man APIs, damit eine neue Ausgabe hinzukommen kann, während die alte für diejenigen weiterhin funktioniert, die noch nicht wechseln können. Dokumentiere den Vertrag — welche Adressen es gibt, welche Felder erwartet werden, was geantwortet wird — damit andere die API nutzen können, ohne deinen Quellcode zu lesen oder zu raten.

Sicherheit gehört dazu

Eine API ist eine Tür zu deinen Daten, oft ohne eine Benutzeroberfläche, die etwas verbergen könnte. Deshalb gilt die Web-Sicherheit in vollem Umfang: Verlange eine Anmeldung und prüfe die Berechtigung bei jedem Aufruf, validiere alle Eingaben auf dem Server, verwende Verschlüsselung beim Transport und überlege, die Zahl der Aufrufe zu begrenzen, die ein Client senden darf, damit die API nicht überlastet werden kann. Eine offene, undokumentierte und unüberwachte API ist ein naheliegendes Ziel.

Eine gute API lässt sich nutzen, ohne den dahinterliegenden Code zu lesen — die Methode, die Adresse und der Statuscode sagen fast alles von selbst.

Gängige Faustregel im API-Design