Blog

API-Design-Reviews durchführen

Mai 15, 2024

Thilo Frotscher zeigt in diesem Artikel, wieso es äußerst wichtig ist, API-Design-Reviews durchzuführen, bevor Schnittstellen in Betrieb gehen.

Das Thema Systemintegration beschäftigt Entwickler:innen bereits seit sehr langer Zeit. Und es ist ein Thema, das bleiben wird. Manches ist über die Jahre gleichgeblieben, etwa Basistechnologien wie HTTP, die Unzuverlässigkeit des Netzwerks oder die Fallacies of Distributed Computing [1]. Andere Aspekte verändern sich: Trends kommen und verschwinden wieder (SOAP), eine API Economy entsteht und der Grad der Vernetzung nimmt immer rasanter zu.

Umso wichtiger ist es, dass Schnittstellen ein gutes Design aufweisen. Aktuell werden überwiegend HTTP APIs eingesetzt. Wer regelmäßig mit diesen arbeitet, wird feststellen, dass zahlreiche APIs nicht sehr gelungen sind, was ihre Betreiber über kurz oder lang vor einige Herausforderungen stellen wird. Aus diesem Grund ist es sehr wichtig, eine API-Design-Review durchzuführen, bevor eine Schnittstelle in Betrieb geht.

Wie lauten die Gründe für schlechtes API-Design? Oftmals ist ein solches sicherlich durch fehlende Erfahrung begründet. In vielen Fällen wird Entwicklungsteams jedoch auch schlicht nicht genügend Zeit eingeräumt, um gewissenhaft am API-Design zu feilen. Denn auf Ebene des Projektmanagements herrscht nicht selten die Ansicht vor, eine HTTP-basierte Schnittstelle müsste mit Hilfe moderner Tools und Frameworks von erfahrenen Entwickler:innen doch im Handumdrehen zu implementieren sein. Das ist im Grunde genommen auch richtig. In der ersten Iteration ist das Design dann jedoch in aller Regel noch nicht sehr durchdacht. Ein gutes API-Design benötigt Zeit – und idealerweise ein Review durch einen erfahrenen API-Experten.

Weshalb ist gutes API-Design eigentlich so wichtig? Einer der wichtigsten Gründe hierfür ist sicherlich, dass Schnittstellen, die zum Zwecke der Systemintegration entwickelt werden, in aller Regel eine sehr lange Nutzungsdauer haben. Sie müssen also über einen längeren Zeitraum betrieben, gewartet und oftmals auch weiterentwickelt werden. Es kommen neue Anforderungen hinzu, etwa bezüglich der Daten, die über die Schnittstellen ausgetauscht werden, bezüglich der Anwendungsfälle oder der Endgeräte, die angebunden werden sollen. Zudem steigt mit der Zeit typischerweise die Anzahl der Nutzer oder Clients. Ist ein API einmal in Betrieb genommen und wird es aktiv von Clients genutzt, ist es nicht mehr beliebig veränderbar. Wer seine Nutzer nicht verärgern möchte, muss daher genau darauf achten, dass bei Änderungen der Schnittstelle die Kompatibilität bisheriger Clients erhalten bleibt. Genau deswegen muss das API-Design bereits bei der ersten Inbetriebnahme der Schnittstelle eine hohe Qualität aufweisen. Dann lässt sich das mit überschaubarem Aufwand bewerkstelligen. Im Falle eines weniger gelungenen Designs werden erste Herausforderungen und Aufwände schon bald sehr deutlich in Erscheinung treten.

 

LUST AUF NOCH MEHR API-TRENDS?

Entdecke Workshops vom 25. - 27. November 2024

Es ist wichtig zu betrachten, in welchem Umfeld ein API eingesetzt wird. Die Einsatzgebiete HTTP-basierter APIs lassen sich grob in fünf Kategorien einteilen.

  1. Backends für webbasierte Anwendungen

  2. Kommunikation innerhalb von Microservices-Architekturen

  3. Integration von Systemen im gleichen Unternehmen

  4. Integration von Systemen einer begrenzten Zahl bekannter Unternehmen (Lieferanten, Geschäftspartner)

  5. öffentliche APIs

Diese Einsatzgebiete unterscheiden sich zum Teil sehr deutlich hinsichtlich der Anzahl der API-Clients und der Bekanntheit oder Nähe zu ihren Entwicklungsteams. Backends für webbasierte Anwendungen haben in der Regel nur einen einzigen Client, und zwar das jeweilige Frontend. Dessen Entwickler:innen sind in aller Regel gut bekannt und gehören dem gleichen Team an. Notwendige API-Änderungen können „auf Zuruf“ vereinbart werden, ohne Rücksicht auf andere Clients nehmen zu müssen. Das API-Design kann genau auf die Use Cases der Anwendung zugeschnitten werden. Völlig anders verhält es sich mit öffentlichen APIs. Diese haben potenziell eine sehr große Anzahl von Clients, die zum Zeitpunkt der Schnittstellenentwicklung typischerweise noch nicht bekannt sind. Gewünschte Operationen, Datenfelder oder angestrebte Use Cases müssen daher ein Stück weit erahnt werden, oder das API-Design muss so generisch und erweiterbar ausgelegt sein, dass es beliebige Einsatzzwecke zulässt. Nicht kompatible Änderungen an öffentlichen APIs sind in aller Regel nur sehr schwierig möglich, sobald die Schnittstelle einmal in Betrieb ist und verwendet wird. Hinzu kommt, dass öffentliche APIs für viele Unternehmen ein Produkt darstellen, das erheblichen Einfluss auf Umsatz und Erfolg haben kann. Manchmal ist das API sogar die zentrale Dienstleistung eines Unternehmens – oder wird im Laufe der Zeit dazu. Das erste API-Design sollte also unbedingt gelingen. Die anderen drei Kategorien bilden unterschiedliche Grauzonen zwischen diesen Extremen. Je nachdem, in welchem Umfeld also ein konkretes API eingesetzt werden soll, ist die Qualität seines Designs also unterschiedlich wichtig. Und das sollte als Entscheidungshilfe dienen, ob überhaupt ein API-Review durchgeführt werden muss, bevor die Schnittstelle in Betrieb geht. Für Backends webbasierter Anwendungen ist das beispielsweise in der Regel nicht notwendig. Doch bereits in Microservice-Anwendungen kann es sehr sinnvoll sein.

Eine API-Design-Review beginnt in der Regel mit einigen grundsätzlichen Fragen. Was ist der Zweck des API? Wer soll es nutzen (Zielpublikum)? Und in welchem der genannten Einsatzszenarien? Die Antworten auf diese Fragen beeinflussen ganz wesentlich, wie das API gestaltet sein sollte. Handelt es sich beispielsweise um ein öffentliches API, dann müssen wir davon ausgehen, dass unternehmensfremde Nutzer möglicherweise manche Abkürzungen oder Bezeichnungen nicht kennen, die im Unternehmen des API-Betreibers geläufig sind. Es muss also darüber nachgedacht werden, ob einzelne Datenstrukturen nach außen gezielt in eine allgemein verständliche Sprache übersetzt werden sollten. Kennt man die künftigen Nutzer des API, so können gewünschte Datenstrukturen und Operationen mit diesen abgestimmt und ein API-Design gemeinsam iterativ erarbeitet werden. Sind die künftigen Nutzer (noch) nicht bekannt, muss das API-Design möglichst generisch sein und grundsätzlich beliebige Anwendungsfälle ermöglichen.

Eine weitere Frage, die sehr früh zu klären ist, ist die nach der angestrebten Strategie für die Versionierung. Soll das API explizite Versionsnummern haben? Falls ja, bedingt das einige Folgefragen, die allesamt nicht leicht zu beantworten sind. Wie wird die jeweilige Version sichtbar gemacht (URL, Headerattribut, Content-Type)? Wie viele Versionen sollen (maximal) gleichzeitig betrieben werden? Und für wie lange werden ältere Versionen weiter unterstützt? Eine Alternative zu expliziten API-Versionen könnte lauten, einfach keine zu haben. Es wäre dann immer nur die jeweils neueste Version des API in Betrieb, die zu beliebigen Zeitpunkten einfach in Betrieb genommen wird. Natürlich kann das nur gelingen, wenn jede neue API-Version rückwärtskompatibel zur vorherigen Version ist, also keine „breaking changes“ mit sich bringt. Ein solches Verfahren ist sehr viel bequemer für den API-Betreiber, bedingt jedoch bereits in der allerersten Version ein API-Design, das leicht erweiterbar ist.

Spätestens an dieser Stelle sollte klar geworden sein, weshalb es so wichtig ist, sich eingehende Gedanken über ein API-Design zu machen und dieses eben auch einer Review zu unterziehen, bevor die erste Version in Betrieb geht. Beim Review werden dann unterschiedliche Aspekte betrachtet, etwa die Themen Konsistenz, Verständlichkeit, Benutzbarkeit, Einhaltung von Standards bzw. Best Practices und Sicherheit. Je nachdem, ob es sich um ein internes oder öffentliches API handelt, wo es zum Einsatz kommt und wie viele Nutzer es hat, sind die einzelnen Aspekte des Reviews natürlich unterschiedlich wichtig.

 

 

Konsistenz

Einer der wichtigsten Punkte ist Konsistenz, und zwar sowohl innerhalb eines API als auch über alle APIs eines Projekts oder sogar eines ganzen Unternehmens hinweg. Denn wenn alle APIs, alle Operationen, Verhaltensweisen und Datenmodelle, eben alles was ein API-Design ausmacht, dem gleichen Ansatz folgen, dann sind diese APIs leichter zu verstehen und zu verwenden. Wer einmal gelernt hat, ein API des Betreibers zu verwenden, dem gelingt der Übergang zum nächsten API wie von selbst, weil dieses eben dem gleichen Design folgt und das gleiche Verhalten aufweist. Das macht bei unternehmensfremden API-Nutzern wie Kunden oder Lieferanten einen guten Eindruck, erleichtert die unternehmensübergreifende Systemintegration und sorgt für eine geringe Last an Supportanfragen. Aber auch unternehmensintern hat Konsistenz im API-Design gewaltige Vorteile. Entwickler:innen können dadurch viel leichter zwischen Projekten wechseln, ohne jedes Mal einen neuen API-Ansatz erlernen zu müssen. Nach Daten zu suchen oder zu filtern, sollte immer gleich funktionieren, unabhängig davon ob man nach Personen, Produkten, Bestellungen oder Lieferanten sucht. Gleiches gilt für das Abfragen, Aktualisieren und Löschen von Daten. Auch Datenformate (Datum, Uhrzeit, metrische Einheiten und Nachkommastellen) sollten konsistent verwendet werden, ebenso Bezeichnungen, Attributnamen und Formate.

Verständlichkeit

Ein weiterer Aspekt des API-Reviews ist die Verständlichkeit der Schnittstelle. Das betrifft unter anderem die Datenstrukturen, ihre Attributnamen, Semantik, Datenformate, Abkürzungen und Codes. Auch die Benennung und Struktur der URL-Pfade zu einzelnen API-Endpunkten sollten betrachtet werden. Sind diese nachvollziehbar und erwartbar? Oftmals existiert in der Fachlichkeit eine natürliche Hierarchie, die idealerweise auch im API-Design zu finden ist. Betrachtet man beispielsweise die Fachdomäne eines fiktiven Karten- oder Adressdiensts, so gibt es auf der Erde mehrere Kontinente, sie enthalten Länder und diese wiederum Städte. Die Städte haben mehrere Straßen usw. Wird diese Struktur von einem API und ihren URL-Pfaden nachgebildet, erhöht das ganz wesentlich ihre Verständlichkeit. Entwickler:innen von API-Clients können dann aufgrund ihres Hintergrundwissens gewisse Strukturen des API bereits erahnen, bevor sie die Dokumentation studieren. Ein API-Reviewer versucht sich daher in die Lage von Cliententwicklern zu versetzen. Was könnten sie erreichen wollen (z. B. eine neue Straße anlegen)? Wie würden sie annehmen, dass das mit dem API funktioniert? Und ist es so tatsächlich möglich oder sieht das API einen gänzlich anderen, eher nicht erwartbaren Weg vor, um eine neue Straße zu erzeugen? Zur Verständlichkeit eines API trägt natürlich in hohem Maße auch dessen Dokumentation bei. Eine API-Spezifikation im OpenAPI-Format ist das Mindeste, was ein API-Betreiber anbieten sollte. In aller Regel ist das jedoch nicht ausreichend. So sind weitere Informationen notwendig, etwa über die Bedeutung von Attributen in Datenformaten oder die Verwendung von Suchfiltern und Operationen. Die Dokumentation muss so geschrieben sein, dass sie für die Nutzer des API leicht verständlich ist. Im Falle öffentlicher APIs sollte die Dokumentation frei von unternehmens- oder brancheninternen Fachbegriffen und Abkürzungen sein.

Benutzbarkeit

Auch eine Betrachtung der Benutzbarkeit ist wichtiger Teil jedes API-Reviews. So gibt es eine ganze Reihe von Operationen, die in fast allen APIs früher oder später benötigt werden und deshalb idealerweise von vornherein Bestandteil des API-Designs sein sollten. Hierzu zählen das schon genannte Suchen und Filtern („Finde alle Bestellungen aus dem Jahr 2022 mit einem Bestellwert von mindestens 1 000 €“). Mindestens genauso wichtig für API-Clients ist die Möglichkeit, ein Limit für die Anzahl der zurückgelieferten Resultate zu spezifizieren und gegebenenfalls seitenweise durch eine Ergebnismenge zu navigieren (Pagination). Denn nur selten wird es sinnvoll oder effizient sein, Tausende oder gar Zehntausende Datensätze auf einmal zum Client zu transportieren. Eine weitere sehr sinnvolle Operation für API-Clients ist die Möglichkeit, anzugeben, in welcher Detailtiefe die Resultate geliefert werden sollen. Bei einer Suche nach Kunden könnten beispielsweise in einem Fall sämtliche bekannten Informationen über diese Kunden angefordert werden (Adresse, Bestellhistorie etc.), in anderen Fällen wären vielleicht nur die Namen und Kundennummern ausreichend. All diese Operationen sollten, wie bereits dargelegt, überall gleich funktionieren, also konsistent implementiert sein. Sie mögen generisch erscheinen, aber genau das ermöglicht es dem API-Betreiber, eine Schnittstelle bereitzustellen, die nicht auf spezifische Use Cases ausgelegt ist, sondern die es jedem einzelnen Nutzer erlaubt, seine eigenen Anwendungsfälle mit Hilfe dieser generischen Operationen umzusetzen. Zur Bewertung der Benutzbarkeit einer Schnittstelle zählt darüber hinaus auch eine Betrachtung der Datenstrukturen und die Frage, wie viele einzelne Requests ein Client senden müsste, um typische Anwendungsfälle umzusetzen. Ist die Anzahl der Requests zu hoch, weist das auf Verbesserungspotenzial im API-Design hin.

Einhaltung von Standards und Best Practices

Ein API-Reviewer sollte auch ein Auge auf die Einhaltung von Standards und Best Practices werfen. Nur selten ergibt es Sinn, von diesen abzuweichen und eigene proprietäre Lösungen zu implementieren. In aller Regel erschwert es nur die Integration des API durch seine Nutzer. Im Falle öffentlicher APIs kann es überdies ein Hinderungsgrund für ihre Verbreitung und damit für ihren Erfolg sein. Zu betrachten ist unter anderem die (korrekte) Verwendung des HTTP-Protokolls, seiner Request-Typen (GETPUTPOSTPATCHDELETE) und Statuscodes. Aber auch für die Benennung von URL-Pfaden oder Queryparametern sollten allgemein bekannte Best Practices eingehalten werden. Im Bereich der Sicherheit sind unbedingt bewährte Standards wie OAuth, OpenID Connect oder JWT zu verwenden.

Idealerweise existiert im Unternehmen eine API-Design-Richtlinie, die einen Designstandard für alle APIs festlegt. Es gibt viele gute (und weniger gute) Wege, HTTP-basierte APIs zu entwerfen, aber Unternehmen sollten sich für ein einheitliches Vorgehen entscheiden. Richtlinien definieren das Aussehen und die Funktionsweise von API-Designs. Wenn sie gut gemacht sind, stimmen sie mit den gängigen Praktiken in der Außenwelt überein, was die Nutzung der APIs noch einfacher gestaltet. Doch selbst wenn solche Richtlinien existieren, gibt es immer noch genügend Möglichkeiten, ungewollte Inkonsistenzen einzubauen. Eben diese aufzudecken, ist eine der Aufgaben der API-Reviews.

Sicherheit

Natürlich ist auch Sicherheit ein sehr wichtiges Thema, und daher ist es unbedingt empfehlenswert, einen Sicherheitsexperten mit einer separaten Prüfung zu beauftragen. Doch einige sicherheitsrelevante Aspekte kann auch der API-Reviewer bereits betrachten. Das betrifft beispielsweise die ausgetauschten Datenstrukturen und die darauf möglichen API-Operationen. Welche Daten und Attribute sind lesbar, welche sollten besser nicht ausgeliefert werden? Welche Daten sind manipulierbar und durch wen? Eine sinnvolle Strategie kann es sein, zunächst nur wenige Daten verfügbar zu machen, eventuell sogar nur die minimale Menge sinnvoll verwendbarer Attribute. Ein API-Betreiber kann dann abwarten, welche weiteren Attribute von API-Nutzern angefragt werden und jeweils im Einzelfall entscheiden, ob diese zugänglich sein sollten. So entsteht schrittweise eine Schnittstelle, die wirklich nur diejenigen Daten ausliefert, die benötigt werden. Auch im Sinne der Rückwärtskompatibilität ist ein solches Vorgehen auf jeden Fall sinnvoller, als nachträglich Attribute aus der Schnittstelle zu entfernen. Für den Zugriff und das Referenzieren einzelner Ressourcen oder Entitäten muss das API auch IDs ausliefern. Aus Sicherheitsgründen ist es hier sehr ratsam, über die Schnittstelle keine internen IDs (wie etwa Primary Keys der Datenbank) bekannt zu machen. Stattdessen sollten alle Ressourcen auch externe IDs haben, die nicht abzählbar und schlecht zu erraten sind. Beispielsweise UUIDs bieten sich hierfür an. Diese müssen dann am Übergang zwischen API und internem System in interne IDs übersetzt werden. Weitere Hinweise zu typischen Sicherheitslücken liefert das OWASP API Security Project [2].

Zusammenfassung

Öffentliche APIs können erheblich zum Umsatz und Erfolg eines Unternehmens beitragen. Sie sollten daher als Produkt verstanden werden. Für manche Unternehmen ist ihr API gar die zentrale Dienstleistung. APIs sollte daher die gleiche Pflege und Gewissenhaftigkeit zuteilwerden, wie jedem anderen Produkt. Das gilt auch für das Design. Doch auch bei internen, nicht öffentlichen APIs ist das Design ein entscheidender Faktor für Erfolg oder Misserfolg der Schnittstelle. Schlechtes Design hat mittelfristig Konsequenzen, etwa Mehraufwände, Supportanfragen, schlechte Erweiterbarkeit und Benutzbarkeit. Eine API-Design-Review durch einen erfahrenen API-Experten ist daher ein wichtiger Bestandteil der API-Entwicklung. Die Review sollte selbstverständlich durchgeführt werden, bevor das API erstmals in Betrieb geht und von Clients genutzt wird. Wichtige Aspekte einer Review sind Konsistenz, Verständlichkeit, Benutzbarkeit, die Einhaltung von Standards und Best Practices und natürlich auch Sicherheit. Diese Aspekte können unterschiedlich gewichtet sein, je nachdem, in welchem Umfeld das API eingesetzt wird.

 

Stay tuned

Immer auf dem Laufenden bleiben! Alle News & Updates:

 

Links & Literatur

[1] Fallacies of Distributed Computing: https://blogs.oracle.com/developers/post/fallacies-of-distributed-systems

[2] OWASP API Security Project: https://owasp.org/www-project-api-security/