07. Oktober 2020
3 Min.

Evolutionäre API-Entwicklung - Die Grundlage

In diesem Blogbeitrag stelle ich den Robustheitsgrundsatz von Postel vor, der die Grundlage für eine sichere evolutionäre API-Entwicklung darstellt.
Evolutionaere API-Entwicklung

Zu Beginn möchte ich erzählen, was in vielen Teams passiert, die zunächst nur mit einer „einfachen API“ anfangen und noch nicht darauf schauen, wie sie sich in Zukunft wohl verändern wird.

API Entwicklung am Anfang des Projekts

Im Schaubild oben sehen wir ein Entwicklungsteam, das sich ganz am Anfang seiner API-Entwicklungs-Reise befindet. Das Team denkt, dass es sehr unwahrscheinlich wäre, Änderungen in der API machen zu müssen. Deshalb entscheidet sich das Team, erst einmal nichts in der Richtung zu machen.

Was passiert, wenn man keine Strategie fuer API Versionierung hat

Ein Jahr später kommt eine neue Anforderung, die größere Änderungen an der Schnittstelle benötigt. Das Team entscheidet, dass es die einfachste Lösung wäre, eine neue Version der geänderten Schnittstelle anzubieten. Als Folge davon sind die Consumer der API, unabhängig davon, ob sie von den Änderungen betroffen sind oder nicht, verpflichtet, ihre Logik an Version 2 anzupassen. Mit dieser Entscheidung hat das Entwicklungsteam seinen Weg für die nächsten Jahre gewählt. Über die Zeit wächst die Anzahl der Versionen die sie unterstützen müssen und die Code-Base, die sie pflegen müssen.

API-Versionierung bedeutet, bei jedem breaking change eine neue Version der API einzuführen.

Robustheitsgrundsatz von Postel

Die Auswahl einer Strategie für die Weiterentwicklung einer API ist wichtig. Aber was ist die Alternative? Ein Ansatz verbirgt sich hinter Postels Gesetz.

Be conservative in what you do, be liberal in what you accept from others.

                                                                                                                   –Jon Postel

Der erste Teil „be conservative in what you do“ beschreibt die Sicht des Providers und bedeutet bei API-Entwicklung, dass er neue Felder und Endpunkte frei hinzufügen, bestehende aber nicht entfernen oder umbenennen darf. Der zweite Teil „be liberal in what you accept from others“  richtet sich an Consumer der API und bedeutet hier, dass alle Felder, die nicht gebraucht werden, ignoriert werden müssen – toleranter Leser. Ich zeige Ihnen anhand eines Beispiel was genau dahintersteckt:

Nehmen Sie an, dass der Provider eines Bibliotheksbestands-Service eine REST API anbietet, um neue Bücher zu erfassen. Er hat zwei Consumern. Ein valider Request sieht so aus:

Felder hinzufügen ist immer okay

In einer zweiten Iteration wird ein neues optionales Feld für Buchbewertung hinzugefügt. Die Consumern sind tolerante Leser, verwenden bisher die Felder: titel, isbn, sprache und autoren und werden nicht von den Änderungen betroffen sein. Die Änderung ist also konservativ im Sinne des Robustheitsgrundsatzes und stellt keinen breaking change dar.

Felder verändern oder entfernen ist ein Problem

Irgendwann stellt ein Consumer fest, dass er zwischen ISBN-10 und ISBN-13 unterscheiden muss. Im aktuellen API-Design gibt es nur ein Feld für die isbn. Dieses Feld entspricht im Prinzip das Format von ISBN-13. Diese Anforderung muss der Provider zunächst in der Schnittstelle umsetzen. Wenn er dem Robustheitsgrundsatz folgt, kann er die Änderungen mit zwei neuen Feldern, isbn13 und isbn10, implementieren:


Zunächst verwenden alle bestehenden Consumer das alte Feld isbn weiter. Auf diese Weise wird auch hier ein breaking change vermieden. Nach und nach können die Consumer die neuen Felder verwenden. In der Praxis möchte ein Provider seine Schnittstellen sauber halten und nicht mehr benötigte Felder schließlich entfernen. Wenn wir das alte Feld entfernen, es aber noch von einem Consumer verwendet wird, würde dieser Consumer nicht mehr funktionieren. Wir hätten also einen breaking change, einen Verstoß gegen den Robustheitsgrundsatz und somit keine evolutionäre API-Entwicklung.

Aber was wenn das zu entfernende Feld von keinem Consumer mehr benutzt wird? Es zu entfernen wäre dann zwar streng genommen ein Verstoß gegen das Robustheitsprinzip, es würden dadurch aber keine negativen Folgen entstehen.

Der Schlüssel zur evolutionären API-Entwicklung liegt also darin, zu wissen, wann ein Feld nicht mehr benutzt wird. Wie sich genau dieses Problem mit Consumer-Driven Contracts lösen lässt, zeige ich Ihnen im nächsten Blog-Beitrag.

Mehr zu unserem Beratungsangebot rund um Consumer-Driven Contracts finden Sie hier.

Bildnachweise: © Rogatnev – stock.adobe.com

Artikel kommentieren