Be Software Architecture Wise
Be Wise Apps

Read in English · Leer en español · Lire en français

Abschnitt 0.6 von 0.8 · Einsteiger · 17 Min. Lesezeit

APIs, JSON und wie getrennte Systeme zusammenarbeiten

Videolektion

5 Min. · auf Englisch gesprochen, mit Untertiteln
Nur anhören (Audio)
Transkript lesen

Denken Sie an die Speisekarte eines Restaurants und seinen Kellner. Die Speisekarte sagt Ihnen genau, was Sie bestellen können. Der Kellner bringt Ihre Bestellung in die Küche und das Gericht zurück. Sie betreten die Küche nie, und die Küche kann ändern, wie sie kocht, ohne dass Sie es merken, solange die Gerichte auf der Karte dieselben bleiben. Software arbeitet mit APIs genau auf diese Weise.

Eine API, eine Programmierschnittstelle, ist der definierte Weg, auf dem eine Software eine andere bittet, etwas zu tun. Das Schlüsselwort ist „definiert“. Eine API ist ein Vertrag, und die Implementierung dahinter bleibt verborgen und kann sich frei ändern. Manche APIs werden innerhalb eines Programms aufgerufen, als gewöhnliche Funktionsaufrufe. Eine Web-API wird über ein Netzwerk aufgerufen, oft zwischen verschiedenen Organisationen, etwa wenn ein Shop mit einem Zahlungsanbieter spricht. Dieser Unterschied ist wichtig. Ein Netzwerkaufruf ist weit langsamer, und er kann auf eine Weise scheitern, wie es ein Funktionsaufruf nicht kann. Die Anfrage kann verloren gehen, oder die Antwort kommt erst, nachdem der Aufrufer aufgegeben hat.

Hier ist ein Web-API-Aufruf. Eine Handy-App, der Client, sendet eine GET-Anfrage über HTTPS und fragt einen Wetteranbieter nach der Vorhersage für Kigali. Die Anfrage erreicht die Wetter-API: den dokumentierten Vertrag des Anbieters. Dahinter bleiben die Prognosedaten intern und verborgen. Die API antwortet mit einem Statuscode, zweihundert, okay, und einem Datenteil in einem Format namens JSON. Beachten Sie, dass der Client nur den Vertrag sieht. Der Anbieter kann alles dahinter ändern, und die App muss es nie erfahren.

Die meisten Web-APIs folgen heute einem Stil namens REST. Eine API stellt Ressourcen bereit, etwa einen Kunden oder eine Bestellung, und jede hat ihre eigene URL. Der Client wirkt mit den Standard-HTTP-Methoden auf sie ein, um abzurufen, anzulegen, zu ersetzen, zu ändern oder zu löschen. Dieselben wenigen Verben funktionieren für jede Ressource. Statuscodes sagen dem Client, was als Nächstes zu tun ist. Einen Vierhunderter-Fehler unverändert zu wiederholen, scheitert erneut, aber einen Fünfhundertdrei etwas später zu wiederholen, kann gelingen. Und die Daten werden meist als JSON übertragen, ein einfaches Textformat aus Namen und Werten, Listen, Zahlen und Text, das jede gängige Sprache lesen kann.

Begleiten wir eine Reise-App, die die Vorhersage für morgen möchte. Zuerst liest sie den Vertrag: welche Adresse aufzurufen ist, wie sie ihren API-Schlüssel sendet, der die App identifiziert, und ein Limit von sechzig Anfragen pro Minute. Sie sendet die Anfrage über HTTPS, sodass Schlüssel und Daten verschlüsselt sind. Solche Schlüssel dürfen nie in den Quellcode geschrieben werden. Sie prüft den Status. Zweihundert bedeutet Erfolg. Vierhunderteins heißt, der Schlüssel ist falsch, vierhundertneunundzwanzig heißt langsamer, und fünfhundertdrei heißt später erneut versuchen. Sie liest aus dem JSON nur die Felder, die sie braucht, etwa die Höchsttemperatur von morgen und die Regenwahrscheinlichkeit. Und der Schritt, den Einsteiger vergessen: Kommt innerhalb von etwa drei Sekunden keine Antwort, zeigt sie die zuletzt gespeicherte Vorhersage statt eines leeren Bildschirms. Jeder Netzwerkaufruf kann langsam sein oder scheitern.

Manchmal muss ein Client wissen, wann etwas geschieht, etwa wenn eine Zahlung gelingt. Er könnte pollen: fragen, schon fertig, immer und immer wieder. Das verschwendet Anfragen, und er erfährt es trotzdem spät. Ein Webhook kehrt die Richtung um. Der Anbieter sendet eine einzige Nachricht an die eigene Adresse des Shops, wenn die Zahlung gelingt. Das geht prompt, aber der Shop muss prüfen, dass jeder Aufruf echt ist, und damit rechnen, dasselbe Ereignis zweimal zu sehen.

Bisher war jeder Aufruf synchron: Der Aufrufer wartet auf die Antwort, wie bei einem Telefonat. Das ist richtig, wenn Sie die Antwort sofort brauchen, etwa: Wurde diese Kartenzahlung genehmigt? Die Alternative ist asynchrones Messaging, eher wie ein Brief, den man einwirft. Wird eine Bestellung aufgegeben, legt der Bestellservice eine Nachricht in eine Queue und macht weiter. Der E-Mail-Service holt sie ab, wenn er bereit ist. Ist der E-Mail-Service eine Stunde lang ausgefallen, warten die Nachrichten in der Queue, statt verloren zu gehen. Der Preis ist, dass der Sender nicht sofort erfährt, ob die Arbeit gelungen ist.

Sobald eine API Nutzer hat, ist jede Änderung heikel. Ein optionales Feld hinzuzufügen, ist meist unbedenklich. Aber eines umzubenennen oder zu entfernen, bricht jeden Client, der sich darauf verlassen hat. Deshalb versionieren Anbieter ihre APIs, lassen alte Versionen für einen veröffentlichten Zeitraum weiterlaufen und kündigen Änderungen lange im Voraus an. Anbieter setzen außerdem Rate Limits, etwa hundert Anfragen pro Minute. Clients sollten ihre Anfragen verteilen und sich zurückhalten, wenn sie dazu aufgefordert werden. Drittanbieter-APIs sparen Monate an Arbeit, aber ihre Ausfälle werden zu Ihren Ausfällen. Verbergen Sie daher jeden Anbieter hinter einer kleinen eigenen Schnittstelle, und planen Sie für den Fall, dass er ausfällt.

APIs sind die Verträge zwischen den Teilen eines Systems, in konkreter Form. Der vollständige Abschnitt enthält die komplette Anfrage und Antwort und mehr zu Schlüsseln und Tokens. Als Nächstes, in Abschnitt null Punkt sieben, geht es um Server und die Cloud.

Was Sie wissen müssen

Was eine API ist

Eine API (Programmierschnittstelle) ist der definierte Weg, auf dem eine Software eine andere bittet, etwas zu tun. Sie legt fest, was angefragt werden kann, was mitgeliefert werden muss, was zurückkommt und was schiefgehen kann. Das entscheidende Wort ist definiert: Eine API ist ein Vertrag. Der Anbieter verspricht, sie funktionsfähig zu halten; der Nutzer verspricht, nur das zu verwenden, was sie beschreibt.

Ein Restaurant ist die übliche Analogie. Die Speisekarte führt auf, was Sie bestellen können und was jedes Gericht enthält; der Kellner bringt Ihre Bestellung in die Küche und das Ergebnis zurück. Sie gehen nicht in die Küche, und Sie müssen nicht wissen, ob der Koch mit Gas oder Induktion kocht. Die Küche kann Ausstattung, Personal und Lieferanten nach Belieben wechseln, solange die Gerichte auf der Karte weiterhin wie beschrieben ankommen. Die Speisekarte ist die API, die Küche ist die Implementierung, und die Trennung zwischen beiden erlaubt es beiden Seiten, sich unabhängig zu ändern.

Das ist derselbe Gedanke wie bei den Schnittstellen in Code organisieren, angewandt auf jeder Ebene. Es ist auch der Grund, warum Architekten APIs so wichtig nehmen: An einer API trifft die Arbeit eines Teams auf die eines anderen, und sobald andere von ihr abhängen, ist sie teuer zu ändern.

In-Process-APIs und Web-APIs

Manche APIs werden innerhalb eines laufenden Programms aufgerufen. Wenn Python-Code json.loads(text) aufruft, nutzt er die API des Moduls json der Standardbibliothek: ein Funktionsaufruf, der Nanosekunden dauert und nur scheitert, wenn die Eingabe fehlerhaft ist. Die öffentlichen Funktionen und Klassen einer Bibliothek sind ihre In-Process-API.

Eine Web-API wird über ein Netzwerk aufgerufen, meist mit HTTP (siehe Wie Computer kommunizieren). Aufrufer und Anbieter können auf verschiedenen Maschinen laufen, in verschiedenen Sprachen geschrieben sein und verschiedenen Organisationen gehören. Eine Mobile-Banking-App spricht mit der Web-API der Bank; die Server der Bank sprechen mit der API eines Kartennetzwerks; ein Shop spricht mit der API eines Zahlungsanbieters.

Der Unterschied ist nicht kosmetisch. Ein Netzwerkaufruf ist tausend- bis millionenfach langsamer als ein Funktionsaufruf, und er kann auf eine Weise scheitern, wie es ein Funktionsaufruf nicht kann: Das Netzwerk verliert die Anfrage, der Server ist überlastet, die Antwort kommt an, nachdem der Aufrufer aufgegeben hat, oder die Anfrage war erfolgreich, aber die Antwort ging verloren, sodass der Aufrufer nicht erkennen kann, ob die Zahlung durchging. Ein Großteil des Entwurfs verteilter Systeme, behandelt in Kapitel 6, dreht sich darum, mit diesen Ausfällen zu leben.

Ein Web-API-Aufruf

Eine Handy-App sendet eine HTTPS-GET-Anfrage an eine Wetter-API, die ihren Datenspeicher liest und eine JSON-Antwort mit Status 200 zurückgibtHandy-Appder ClientWetteranbieterWetter-APIdokument. VertragPrognosedatenintern, verborgenGET /v1/forecast?city=Kigali200 OKJSON-BodyClients sehen nurden Vertrag
Der Client sieht nur den Vertrag der API; wie der Anbieter Prognosen speichert und berechnet, bleibt dahinter verborgen.

REST: Ressourcen, URLs und Verben

Die meisten Web-APIs folgen heute dem Stil namens REST (Representational State Transfer), den Roy Fielding in seiner Dissertation von 2000 beschrieb. Fielding definierte REST als eine Reihe von Randbedingungen für große vernetzte Systeme wie das Web; im Alltag meint „eine REST-API“ etwas Einfacheres: eine HTTP-API, die um Ressourcen herum organisiert ist.

Eine Ressource ist etwas, das die API bereitstellt: ein Kunde, eine Bestellung, eine Prognose. Jede hat eine URL, etwa /orders/1042. Auch eine Sammlung davon hat eine URL, etwa /orders. Der Client wirkt mit den Standard-HTTP-Methoden auf Ressourcen ein, liest den Statuscode des Ergebnisses und tauscht Daten im Body aus, meist als JSON. Dieselben wenigen Verben funktionieren daher für jede Ressource, was gut entworfene REST-APIs vorhersehbar macht.

Eine Ressource, die Standardverben

AnfrageBedeutungTypischer Erfolgsstatus
GET /orders?customer=42Bestellungen auflisten, gefiltert über einen Query-Parameter. Lesezugriffe ändern nie etwas.200 OK
GET /orders/1042Eine Bestellung abrufen.200 OK (oder 404 Not Found, wenn es diese Bestellung nicht gibt)
POST /ordersEine neue Bestellung aus dem JSON im Body der Anfrage anlegen.201 Created, mit der URL der neuen Bestellung
PUT /orders/1042Bestellung 1042 durch die gesendete Repräsentation ersetzen.200 OK oder 204 No Content
PATCH /orders/1042Nur einige Felder ändern, etwa die Lieferadresse.200 OK
DELETE /orders/1042Die Bestellung stornieren oder entfernen.204 No Content

Statuscodes tragen eine Bedeutung, auf die ein Client-Programm reagieren kann. Ein 4xx-Code besagt, dass der Client etwas falsch gemacht hat: 400 bei einer fehlerhaften Anfrage, 401, wenn Zugangsdaten fehlen oder ungültig sind, 403, wenn der Aufrufer bekannt, aber nicht berechtigt ist, 404, wenn die Ressource nicht existiert, 429, wenn er zu viele Anfragen gesendet hat. Ein 5xx-Code besagt, dass der Server versagt hat: 500 bei einem unerwarteten Fehler, 503, wenn er vorübergehend nicht verfügbar ist. Die Unterscheidung ist wichtig, weil eine unveränderte Wiederholung einer 4xx-Anfrage erneut scheitert, während eine Wiederholung nach einem 503 etwas später gelingen kann.

Daten werden als JSON (JavaScript Object Notation) übertragen, einem Textformat, das als RFC 8259 standardisiert ist. Es hat nur wenige Bausteine: Objekte (Name-Wert-Paare in geschweiften Klammern), Arrays (Listen in eckigen Klammern), Zeichenketten in doppelten Anführungszeichen, Zahlen, true, false und null. Trotz des Namens kann jede gängige Sprache es lesen und schreiben, weshalb es zur gemeinsamen Sprache der Web-APIs wurde. Es gibt andere Stile für andere Bedürfnisse: Bei GraphQL gibt der Client genau an, welche Felder er haben will, und gRPC nutzt ein kompaktes Binärformat für schnelle Aufrufe zwischen Services; Kapitel 6 vergleicht sie.

Ausgearbeitetes Beispiel

Ausgearbeitetes Beispiel: eine Wetter-API aufrufen

Eine Reise-App möchte die Wettervorhersage für morgen in Kigali. Der Anbieter (hier ein erfundenes api.example.com) dokumentiert einen Endpoint (eine URL, die eine bestimmte Art von Anfrage annimmt) und stellt der App einen API-Schlüssel aus.

1. Den Vertrag lesenDie Dokumentation sagt: GET /v1/forecast mit den Query-Parametern city und days; den Schlüssel in einem Authorization-Header senden; Antworten sind JSON; Limit 60 Anfragen pro Minute.
2. Die Anfrage sendenDie App sendet die unten gezeigte HTTP-Anfrage über HTTPS, sodass Schlüssel und Daten bei der Übertragung verschlüsselt sind.
3. Den Status prüfen200 bedeutet, dass der Body eine Vorhersage enthält. 401 bedeutet, dass der Schlüssel falsch ist; 429 heißt langsamer; 503 heißt später erneut versuchen.
4. Das JSON auswertenDie App liest days[0].max_c und days[0].rain_chance und ignoriert Felder, die sie nicht braucht.
5. Fehler behandelnKommt innerhalb von, sagen wir, 3 Sekunden keine Antwort, zeigt die App die letzte zwischengespeicherte Vorhersage statt eines leeren Bildschirms.

Jeder Schritt hängt vom Vertrag ab, nicht davon, wie der Anbieter Vorhersagen berechnet. Der Anbieter kann morgen auf neue Server oder ein neues Wettermodell umsteigen, ohne dass sich die App ändert.

Schritt 5 ist der Schritt, den Einsteiger vergessen: Jeder Aufruf über ein Netzwerk kann langsam sein oder scheitern, daher muss der Aufrufer entscheiden, was dann geschieht.

GET /v1/forecast?city=Kigali&days=2 HTTP/1.1
Host: api.example.com
Authorization: Bearer sk_test_4f9a...
Accept: application/json

HTTP/1.1 200 OK
Content-Type: application/json

{
  "city": "Kigali",
  "units": "metric",
  "days": [
    {"date": "2026-10-23", "min_c": 16, "max_c": 27, "rain_chance": 0.6},
    {"date": "2026-10-24", "min_c": 16, "max_c": 26, "rain_chance": 0.4}
  ]
}
Anfrage und Antwort aus dem ausgearbeiteten Beispiel.
import os
import requests

API_KEY = os.environ["WEATHER_API_KEY"]   # never hard-code secrets

resp = requests.get(
    "https://api.example.com/v1/forecast",
    params={"city": "Kigali", "days": 2},
    headers={"Authorization": f"Bearer {API_KEY}"},
    timeout=3,                 # give up after 3 seconds
)
resp.raise_for_status()        # raises an error for 4xx and 5xx
tomorrow = resp.json()["days"][0]
print(tomorrow["max_c"], "degrees, rain chance", tomorrow["rain_chance"])
Derselbe Aufruf aus Python mit der verbreiteten Bibliothek requests, einschließlich Timeout und Statusprüfung.

Wer ruft an? API-Schlüssel und Tokens

Die meisten APIs müssen wissen, wer aufruft, um abzurechnen, zu begrenzen und zu entscheiden, was der Aufrufer sehen darf. Zwei Begriffe sollte man von Anfang an trennen. Authentifizierung beantwortet „Wer sind Sie?“; Autorisierung beantwortet „Was dürfen Sie tun?“

Ein API-Schlüssel ist eine lange geheime Zeichenkette, die die aufrufende Anwendung identifiziert und mit jeder Anfrage gesendet wird, typischerweise in einem Header. Er ist einfach und identifiziert ein Programm, keine Person. Ein Access Token ist ein kurzlebiger Berechtigungsnachweis, der nach einer Anmeldung ausgestellt wird, oft im Namen eines bestimmten Nutzers und mit bestimmten Berechtigungen („den Kalender dieses Nutzers lesen, aber nicht seine E-Mails“); er wird meist als Authorization: Bearer <token> gesendet. Tokens laufen ab, sodass ein gestohlenes nur begrenzte Zeit nützt. Die zugrunde liegenden Standardprotokolle, OAuth 2.0 und OpenID Connect, werden in Identität und Zugriff behandelt.

Was auch immer verwendet wird, die Regeln sind dieselben: Zugangsdaten nur über HTTPS senden, sie aus dem Quellcode heraushalten und aus mobilen Apps, aus denen jeder sie extrahieren kann, sie in einem Secrets Manager oder in Umgebungseinstellungen speichern und sie schnell widerrufen und ersetzen können.

Webhooks: Die API ruft Sie zurück

Manchmal muss der Client wissen, wann auf der Seite des Anbieters etwas geschieht: Eine Zahlung gelingt, ein Paket wird zugestellt, ein Dokument wird unterschrieben. Der Client könnte pollen, also alle paar Sekunden fragen „Ist es schon passiert?“, was Anfragen verschwendet und es trotzdem spät bemerkt. Ein Webhook kehrt die Richtung um: Der Client registriert eine eigene URL, und der Anbieter sendet ein HTTP-POST an diese URL, wenn das Ereignis eintritt. Den Begriff prägte Jeff Lindsay 2007.

Polling und Webhook im Vergleich zwischen einem Shop und einem ZahlungsanbieterPollingWebhookShopZahlungs-anbieter„Fertig?“ immerwieder ...Shop/hooks/paymentsZahlungs-anbieterEin HTTP-POST, wenndie Zahlung gelingtViele unnötige Anfragenund Verzögerung bis zum Polling-IntervallPrompt, aber der Shop mussprüfen, deduplizieren, erreichbar sein
Polling fragt wiederholt; ein Webhook wartet darauf, informiert zu werden, um den Preis neuer Pflichten für den Empfänger.

Webhooks bringen Pflichten mit sich. Der empfangende Endpoint steht im öffentlichen Internet, daher muss er prüfen, dass jeder Aufruf wirklich vom Anbieter stammt, meist durch Verifizieren einer kryptografischen Signatur in einem Header. Anbieter wiederholen den Versand, wenn der Empfänger nicht antwortet, sodass dasselbe Ereignis zweimal ankommen kann und der Empfänger Duplikate erkennen muss (die Verarbeitung eines Duplikats darf die Bestellung nicht zweimal versenden). Und Ereignisse können in falscher Reihenfolge ankommen.

Auf eine Antwort warten oder nicht: synchron und asynchron

Alles bisher war synchron: Der Aufrufer sendet eine Anfrage und wartet auf die Antwort, bevor er weitermacht, wie bei einem Telefonat. Das ist leicht nachzuvollziehen und die richtige Wahl, wenn der Aufrufer die Antwort wirklich sofort braucht, etwa „Wurde diese Kartenzahlung genehmigt?“. Die Schwäche: Der Aufrufer ist nur so verfügbar und so schnell wie alles, worauf er wartet.

Die Alternative ist asynchrones Messaging, eher wie ein Brief, den man in einen Briefkasten wirft. Der Sender legt eine Nachricht in eine Message Queue und macht weiter. Der Empfänger holt Nachrichten aus der Queue, wenn er bereit ist. Ist der Empfänger langsam oder eine Stunde lang ausgefallen, warten die Nachrichten, statt zu scheitern. Wenn der Shop eine Bestellung bestätigt, muss das Senden der Bestätigungs-E-Mail den Bildschirm des Kunden nicht aufhalten; eine Nachricht OrderPlaced kann in eine Queue gehen, die der E-Mail-Service einen Moment später abarbeitet.

Synchroner Aufruf und asynchrone Nachricht über eine Queue im VergleichSynchron: Der Aufrufer wartet auf die AntwortBestellservicewartet ...Zahlungs-APIantw. sofort1. Anfrage: 24,50 belasten2. Antwort: genehmigtAsynchron: Der Sender legt eine Nachricht ab und macht weiterBestellservicemacht weiterMessage Queuehält NachrichtenE-Mail-Serviceliest, wenn bereitOrderPlacedspäterFällt der E-Mail-Service aus, warten Nachrichten in der Queue, statt verloren zu gehen.
Ein synchroner Aufruf bindet den Aufrufer an die Verfügbarkeit des Aufgerufenen; eine Queue entkoppelt sie zeitlich.

Asynchronität ist nicht kostenlos. Der Sender erfährt nicht sofort, ob die Arbeit gelungen ist, das System wird schwerer nachzuverfolgen und zu testen, und Nachrichten können mehr als einmal zugestellt werden. Die Entscheidung, welche Interaktionen synchron und welche asynchron sein sollen, ist eine der zentralen Entscheidungen in verteilten Systemen und wird ausführlich in Kommunikation und APIs und Queues und Backpressure behandelt.

Entscheidungshilfe

Entscheidungshilfe: jetzt aufrufen oder eine Nachricht senden?

Eine erste Orientierung für eine Interaktion zwischen zwei Teilen eines Systems. Kapitel 6 verfeinert sie.

  1. Braucht der Aufrufer das Ergebnis, bevor er seinem eigenen Nutzer antworten kann (zum Beispiel, ob die Karte genehmigt wurde)?
    JaNutzen Sie einen synchronen Aufruf, mit einem Timeout und einem Plan für den Fall, dass die andere Seite langsam oder ausgefallen ist.
    NeinWeiter zur nächsten Frage.
  2. Kann die Arbeit ein paar Sekunden oder Minuten später geschehen, ohne dass es jemand merkt (eine E-Mail senden, einen Bericht aktualisieren)?
    JaSenden Sie eine asynchrone Nachricht über eine Queue, damit ein langsamer oder ausgefallener Empfänger den Aufrufer nicht aufhält.
    NeinWeiter zur nächsten Frage.
  3. Ist die Arbeit langsam (Sekunden bis Stunden), etwa das Erzeugen eines großen Exports?
    JaNehmen Sie die Anfrage sofort an (zum Beispiel mit 202 Accepted), erledigen Sie die Arbeit über eine Queue, und teilen Sie dem Client per Webhook oder über eine abfragbare Status-URL mit, wann sie fertig ist.
    NeinEin einfacher synchroner Aufruf genügt meist; halten Sie ihn schnell und setzen Sie ein Timeout.

Mit den APIs anderer leben: SDKs, Versionen und Limits

Viele Anbieter veröffentlichen ein SDK (Software Development Kit): eine Bibliothek für jede verbreitete Sprache, die die HTTP-Aufrufe in gewöhnliche Funktionen verpackt, sodass ein Entwicklungsteam client.refunds.create(payment_id) schreibt, statt Anfragen von Hand zu bauen. SDKs sparen Zeit und kümmern sich um Details wie Wiederholungen und Signaturen, sind aber eine weitere Abhängigkeit, die aktuell gehalten werden muss.

Sobald eine API Nutzer hat, wird jede Änderung heikel. Ein neues optionales Feld in einer Antwort hinzuzufügen, ist meist unbedenklich. Ein Feld umzubenennen, zu entfernen, seinen Typ oder seine Bedeutung zu ändern oder eine optionale Eingabe zur Pflicht zu machen, ist ein Breaking Change: Jeder Client, der sich auf das alte Verhalten verlassen hat, bricht, oft in Produktion und oft bei einem Anbieter, der diese Clients weder sehen noch aktualisieren kann (denken Sie an mobile Apps, die Nutzer nie aktualisieren). Anbieter versionieren ihre APIs daher, zum Beispiel mit /v1/ und /v2/ in der URL oder mit einem Versions-Header, lassen die alte Version für einen veröffentlichten Zeitraum weiterlaufen und kündigen Deprecations (Hinweise, dass eine Funktion zurückgezogen wird) lange im Voraus an. Hyrum Wrights Beobachtung, bekannt als Hyrums Gesetz, fügt eine Warnung hinzu: Bei genügend Nutzern hängt jemand von jedem beobachtbaren Verhalten einer API ab, auch von solchem, das die Dokumentation nie versprochen hat.

Anbieter schützen sich außerdem mit einem Rate Limit: einer Obergrenze wie 100 Anfragen pro Minute und Schlüssel. Anfragen über dem Limit werden mit Status 429 Too Many Requests abgelehnt, oft mit einem Retry-After-Header, der angibt, wann man es erneut versuchen kann. Clients sollten das respektieren, ihre Anfragen verteilen, Antworten zwischenspeichern, die sich selten ändern, und sich zurückhalten, wenn sie dazu aufgefordert werden.

Drittanbieter-APIs nutzen: selbst bauen oder einkaufen

Moderne Anwendungen werden ebenso zusammengesetzt wie geschrieben. Eine Essensliefer-App nutzt vielleicht die API eines Zahlungsanbieters für Kartenzahlungen, eine Karten-API für Adressen und Routen, eine E-Mail- oder SMS-API für Belege und einen Push-Benachrichtigungsdienst für „Ihr Fahrer ist in der Nähe“. Jede davon spart Monate an Spezialistenarbeit und bringt Fachwissen mit (Kartensicherheit, globale Kartendaten, E-Mail-Zustellbarkeit), mit dem nur wenige Teams mithalten könnten.

Jede bringt aber auch eine Abhängigkeit mit, die das Team nicht kontrolliert: Die Ausfälle des Anbieters werden zu Ihren Ausfällen, seine Preisänderungen zu Ihren Kosten, sein Umgang mit Daten wird Teil Ihrer Compliance, und ein Wechsel kann bedeuten, Code neu zu schreiben. Fachleute steuern das bewusst. Sie isolieren jeden Anbieter hinter einer kleinen eigenen Schnittstelle, sodass nur ein Teil des Codes die API des Anbieters kennt; sie setzen Timeouts und legen fest, was geschieht, wenn der Anbieter ausgefallen ist; sie beobachten die Statusseite und das Änderungsprotokoll des Anbieters; und sie halten fest, was ein Wechsel kosten würde.

Warum das für die Architektur wichtig ist

Architektur dreht sich weitgehend um die Teile eines Systems und die Verträge zwischen ihnen, und APIs sind diese Verträge in konkreter Form. Eine API, die sich leicht richtig nutzen und schwer kaputt machen lässt, lässt Teams parallel arbeiten und ihr Innenleben frei ändern; eine undichte oder instabile koppelt alle an alle. Die Wahl zwischen synchronen Aufrufen und asynchronen Nachrichten bestimmt, wie sich Ausfälle ausbreiten. Kapitel 3 erklärt die Prinzipien hinter guten Schnittstellen (Information Hiding, Abstraktion und Schnittstellen), und Kapitel 6 zeigt, wie Entscheidungen über APIs und Messaging verteilte Systeme gelingen oder scheitern lassen.

Prüfen Sie Ihr Verständnis

Welcher Teil der Restaurant-Analogie entspricht der API, welcher der Implementierung?

Die Speisekarte (und die Art, wie der Kellner Bestellungen aufnimmt) ist die API: die vereinbarte Liste dessen, was angefragt werden kann und was zurückkommt. Die Küche ist die Implementierung, die sich frei ändern kann, solange die Versprechen der Speisekarte eingehalten werden.

Was ist der Unterschied zwischen einer 404- und einer 503-Antwort, und welche lohnt einen späteren erneuten Versuch?

404 Not Found besagt, dass die angefragte Ressource nicht existiert, ein Problem auf Client-Seite, das eine Wiederholung nicht behebt. 503 Service Unavailable besagt, dass der Server vorübergehend nicht antworten kann, daher kann eine Wiederholung nach einer Pause gelingen.

Warum muss ein Webhook-Empfänger damit rechnen, dasselbe Ereignis zweimal zu erhalten?

Anbieter wiederholen den Versand, wenn sie nicht rechtzeitig eine Erfolgsantwort erhalten, selbst wenn die erste Zustellung tatsächlich verarbeitet wurde; Duplikate sind also normal. Der Empfänger muss ein bereits behandeltes Ereignis erkennen und nicht erneut darauf reagieren.

Ist das Hinzufügen eines neuen optionalen Felds zu einer JSON-Antwort normalerweise ein Breaking Change?

Meist nicht, weil sich gut verhaltende Clients Felder ignorieren, die sie nicht kennen. Ein Feld zu entfernen oder umzubenennen oder seinen Typ zu ändern, ist dagegen ein Breaking Change.

Weiter · 0.7Server und die CloudWas Server und Rechenzentren sind, wie virtuelle Maschinen und Container sich Hardware teilen, was IaaS, PaaS, SaaS und Serverless dem Anbieter überlassen und wie Regionen, Zonen, CDNs und Skalierung zusammenpassen.Weiter →

Quellen und weiterführende Literatur

Haben Sie eine Frage zu diesem Abschnitt? ArchitectBot, der KI-Lernassistent des Kurses, antwortet zuerst aus dem Kurs.

Fragen: „Wann sollte ein Teil meines Systems einen anderen mit einer synchronen API-Anfrage aufrufen, und wann sollte er stattdessen eine Nachricht über eine Queue senden?“