Statistik

API-ARCHITEKTUR

Offene Schnittstellen durch API-Architektur gestalten

Richtiger Schnitt, Wiederverwendbarkeit und Lifecycle durch API-Architektur

Im Umfeld von offenen Schnittstellen muss die API-Architektur und dabei insbesondere nicht-funktionale Anforderungen betrachtet werden. Offene Schnittstellen sind nicht nur eine Frage der Datenstruktur, der abgebildeten Funktion, der Technologie oder Tools. Hier einige Beispiele möglicherweise konkurrierender Anforderungen, deren Priorität abzuwägen ist:

  • In welcher Zeit benötige ich spätestens eine Antwort?
  • Wie hoch wird die Aufrufrate sein?
  • Muss die Datenkonsistenz im Zusammenhang mit den ersten beiden Punkten immer zu 100% gewährleistet sein?
  • Wer sind die Konsumenten und wird die API auch durch Externe außerhalb des Unternehmens aufgerufen und sind hierdurch SLAs zu beachten?
  • Welche fachliche oder technische Motivation (Zweck) steckt dahinter?

Nachfolgend gehen wir näher auf eine Auswahl von Aspekten der API-Architektur ein, die insbesondere bei der Realisierung von offenen Schnittstellen berücksichtigt werden sollte.

Synchrone oder asynchrone Kommunikation

API-Architektur-1-Kommunikation

Die Frage der API-Architektur nach der Synchronität einer Schnittstelle lässt sich nur beantworten, wenn messbare Anforderungen für maximale Antwortzeit im Zusammenhang mit Aufrufrate, Datenmenge und Datenkonsistenz definiert sind. Wenn Statistiken zum Verhalten von Frontend-Benutzern und angefallene Daten der letzten Jahre existieren, so lassen sich davon Anforderungen ableiten.
Sobald die Anforderungen an die Schnittstelle geklärt sind, erfolgt die Analyse der Backendsysteme bezüglich Unterstützung der geforderten Leistung und technischer Machbarkeit.
Wenn das angefragte System nicht alle Anforderungen erfüllt, ist das Szenario insbesondere aus fachlicher Sicht auf Alternativen zu untersuchen.

Der Einsatz einer synchronen oder asynchronen Kommunikation wird im Einzelfall anhand der benötigten Eigenschaften der Schnittstelle entschieden, denn eine hohe Anzahl paralleler synchroner Anfragen kann zu Blockaden/Deadlocks führen. Aus Geschäftsprozess- bzw. Benutzersicht sind blockierende Situationen möglichst auszuschließen. Sie können aber bei synchronem Verhalten mit hoher paralleler Aufrufrate nicht vermieden werden.
Lässt sich ein temporärer Zugriffskonflikt für den Benutzer durch einfache Mechanismen wie sprechende Fehlermeldung und Wiederholung der Anfrage vermeiden?
Hinzu kommt: hohe Anfragerate und Datenkonsistenz konkurrieren bei verteilten Systemen vergleichbar zu den bei Datenbanken bekannten CAP Theorem. In Folge dessen können nur zwei von drei Anforderungen (Konsistenz, Verfügbarkeit und Partitionstoleranz – bei Cloud-Anwendungen vorausgesetzt) zu 100% erfüllt werden. Ist in diesem Zusammenhang eine „schlussendliche“ Konsistenz mit kleinstmöglichem Zeitverzug fachlich vertretbar?
Oft können angefragte Systeme aufgrund ihrer Batch- oder Prozessverarbeitung nicht in der Zeit antworten, die ein Frontenduser beim Klick eines Buttons wartet. Alternativen sind hier eine asynchrone Kommunikation in Form eines Websockets oder ein erneuter Aufruf zu einem späteren Zeitpunkt zur Abfrage des Prozessstatus.
In allen Fällen ist bei asynchronen Aufrufen ein Monitoring notwendig, das auf „Langläufer“ bzw. Abbrüche hinweist, um Blockaden im Geschäftsprozess zu vermeiden und Durchlaufzeiten zu analysieren.
Insgesamt ist ein asynchroner Architekturstil vorzuziehen, da damit parallele Aufrufe zu keinem blockierenden Verhalten führen. Dies ist aber mit höherer Komplexität und Aufwand verbunden.

Wiederverwendbarkeit von Schnittstellen

API-Architektur-2-Wiederverwendbarkeit-von-Schnittstellen

Bei der Frage, ob eine Schnittstelle wiederverwendbar konzipiert wird, stehen oft Projektinteressen gegen Unternehmensinteressen. Das Projekt benötigt eine Schnittstelle, die genau auf den Kontext zugeschnitten ist. Für eine Analyse, ob es potentiell weitere Nutzer für eine Schnittstelle gibt, besteht in der Regel keine Zeit. Für das Unternehmen ist es aber sinnvoll, Schnittstellen, wo möglich, wiederzuverwenden, weil das sowohl in der Entwicklung als auch im Betrieb Kosten spart.
Anforderungen an Schnittstellen ergeben sich aus jedem individuellen Kontext unterschiedlicher Aufrufe. Beim Begriff des „Kunden“ beispielsweise können aus Sicht des Aufrufers A die Kontaktdaten eines Kunden erforderlich sein. Beim Aufrufer B ist aber die Lieferadresse erforderlich. In beiden Kontexten sind unterschiedliche Anforderungen an die hinter der Schnittstelle umzusetzende Logik erforderlich.

Sind die Anforderungen beider Anwender zeitgleich bekannt, kann die Wiederverwendung oder die separate Umsetzung der Schnittstelle abgewogen werden. Sind die Anforderungen weiterer Konsumenten der Schnittstelle noch nicht bekannt, kann nicht automatisch von einer Wiederverwendung ausgegangen werden.
Eine Hürde für die Wiederverwendbarkeit von Schnittstellen liegt auch in der Begrifflichkeit unterschiedlicher Domänen (z.B. zweier Abteilungen). Trotzdem könnten fachliche Gemeinsamkeiten genutzt werden, beispielsweise durch Nutzung in einer Branche normierter Datenstrukturen.
Ein weiterer Aspekt, der für die Wiederverwendbarkeit spricht, ist die Reduzierung der Komplexität und Vermeidung des Aufblähens vom API Repository. Redundanzen führen meist zu immensen Folgeaufwänden, die im späteren Verlauf wieder schwer abzubauen sind. Aus diesem Grund sollte eine API-Strategie zur Unternehmensstrategie und umgekehrt passen. Eine „API-isierung“ sollte nie aus technischen Gründen allein erfolgen, sondern der Geschäftsstrategie und der daraus resultierenden Motivation folgen.

Dokumentation von Schnittstellen

API-Architektur-3-Dokumentation-von-Schnittstellen

Damit die gewählte API-Architektur für viele Konsumentengruppen zugänglich ist und auch betreibbar bleibt, muss die Dokumentation einer Schnittstelle für verschiedene Blickwinkel verständlich, inhaltlich vollständig und zugreifbar sein. Der notwendige Aufwand zahlt sich in reduzierten Zeiten aller Beteiligten im Test, im Fehlerfall oder bei Änderungsbedarf aus.
Ein Entwickler versteht die Dokumentation einer Schnittstelle oft als eher technische Dokumentation der einzelnen Methoden, ihrer Aufrufpfade und Datenstrukturen. Diese ist für ihn selbsterklärend, aufwandsschonend und basiert auf Standards wie OpenAPI (vormalig: Swagger) für REST Schnittstellen die von den meisten Tools und Entwicklungsframeworks unterstützt werden. Auch eine Spezification by Example ist ein effektiver Ansatz, um ein gemeinsames Verständnis über APIs herzustellen, hierzu siehe: Consumer Driven Contract Testing.

Für die Fachseite ist zusätzlich die Funktion der Schnittstelle, also das Verhalten in Abhängigkeit der übermittelten Datenkonstellation, relevant. Dies ist sowohl bei der Erstellung von Schnittstellen im eigenen Kontext als auch bei Wiederverwendungen eine unverzichtbare Information. Für Test und Betrieb sind bei der funktionalen Beschreibung nicht nur die positiven, sondern auch alle negativen Fälle relevant, um einen vollständigen Test durchführen und im Betrieb die korrekte Funktion überprüfen zu können. Für jeden Fehler sollte eine eindeutige, in Test und Betrieb messbare Kennung existieren. Insbesondere müssen auch nicht-funktionale Aspekte als testbare Anforderungen dokumentiert sein. Die über die Schnittstelle abrufbaren Daten dürfen nur für eindeutig authentifizierte Aufrufer mit notwendigen Zugriffsrechten zugreifbar sein. Nicht zuletzt muss die Dokumentation messbare SLA-Kriterien zu Performance (Antwortzeit, Durchsatz, Logging und Monitoring) enthalten.

Schnittstellen richtig schneiden - definiert die Qualität der API-Architektur

Viele kleine Schnittstellen, die genau eine Funktion erfüllen, können zu Antwortzeitproblemen durch die Latenz in der Netzwerkinfrastruktur führen, wenn Aufrufe mehrerer Schnittstellen notwendig sind, um eine Anwenderanfrage zu bedienen. Anderseits erlauben sie hohe Durchsatzraten, wenn die Anwenderanfrage mit genau einer Schnittstelle die Anfrage beantworten kann. Beispiel: „Ich möchte eine generische Schnittstelle für die Bestellung unterschiedlicher Produkte haben und Einzelschnittstellen pro Produkt vermeiden.“ Versus „Ich benötige eine Schnittstelle für die Bestellung genau eines Produkttyps.“
API-Architektur-4-Schnittstellen-richtig-schneiden

Beim Schneiden von Webservice-Schnittstellen gilt es, individuelle Faktoren für eine gute API-Architektur abzuwägen.
Grundsätzlich ist der Funktionsumfang zu beschränken und von anderen Services inhaltlich abzugrenzen, um den Service von einem einzelnen Team unabhängig entwickeln und ausliefern lassen zu können.

Ein weiterer Vorteil für die Größenbeschränkung liegt in der technischen Skalierbarkeit, um die Performance einzelner Funktionsblöcke an den Bedarf anzupassen (Beispiel Produktsuche vs. Produktverkauf).

Meist ergeben sich individuelle Anforderungen wie Datenaggregation oder Antwortzeitverhalten aus dem Datenbedarf eines Geschäftsprozessschrittes oder der Anwendungsmasken. Sind Netzwerkinfrastruktur oder Middleware Zeitfresser, kann ein gröberer Schnittstellenschnitt hilfreich sein. Man sollte aber im Blick behalten, dass ein grober Serviceschnitt die Wahrscheinlichkeit der Wiederverwendbarkeit aller Attribute in einem anderen Kontext verringert.

In allen Fällen zahlt es sich aus, wenn für das Unternehmen ein einheitliches und verbindliches Regelwerk zur API-Entwicklung existiert, an dem sich alle Beteiligten ausrichten können oder sogar müssen. Dies betrifft zum einen die technischen aber auch die fachlichen Aspekte, um den passenden Zuschnitt zu finden. Ein „one-fits-all“ Ansatz kann und wird es aber nicht geben.

Funktionale versus qualitative (nicht-funktionale) Anforderungen

Kontext-getriebene-Architektur-9-Fazit

Für das Business stehen die fachlichen Anforderungen normalerweise im Vordergrund. Kleine Budgets und hoher Wettbewerbsdruck führen dazu, dass man technische Aspekte vernachlässigt. Das Team, das eine Schnittstelle betreiben soll, erwartet aber eine robuste und stabile Anwendung, die Instrumente mitbringt, eine schnelle Fehleranalyse und -behebung durchführen zu können.

Projekte müssen für den Erfolg der API-Architektur bereits in der Planung funktionale und nicht-funktionale Anforderungen berücksichtigen und budgetieren.

In einer cloud-basierten Anwendung kommunizieren viele kleine Module miteinander. Es gilt, Fehlersituationen bereits im Design zu berücksichtigen, um blockierendes Verhalten, Gesamtausfall und Instabilität zu vermeiden. Daher ist es sehr zu empfehlen, dass alle Module und ihre Kommunikation untereinander analysierbar sind und in Echtzeit auf Fehler und Einhaltung definierter SLAs überwachbar sind.
Nicht-funktionale Anforderungen wie Security, Logging, Tracing, Monitoring, Service-Kataloge, Routing müssen nicht zwingend in den Services ausprogrammiert werden. Service-Mesh (Service-Netz) Tools wie Istio trennen diese Aspekte, indem Services in Containern (Kubernetes) eingespielt und die genannten nicht-funktionalen Aspekte zur Laufzeit in der Infrastruktur konfigurativ aktiviert werden.
Für nicht-funktionale Anforderungen sind aus fachlicher und technischer Sicht testbare Szenarien mit messbaren Ergebnissen zu erstellen und möglichst in jedem Release-Test zu überprüfen.

Sicherheit und Robustheit - aufgeteilt in der API-Architektur

API-Architektur erfordert Schnittstellen/Webservices für diverse Sicherheitsaspekte abzusichern:

  • Authentizität des Aufrufers,
  • Autorisierung des Aufrufers,
  • Integrität (Unveränderbarkeit der Daten bei der Übermittlung),
  • inhaltliche Zugriffsbeschränkung auf Datenelemente,
  • DSGVO,

Eine Sicherheitslücke mit entsprechender Eintrittswahrscheinlichkeit ist meist ein finanzielles Risiko in erheblichem Umfang bis zur Existenzbedrohung. Im Einzelfall muss natürlich die Kritikalität und Wahrscheinlichkeit eines möglichen Missbrauchs berücksichtigt werden.

API-Architektur-6-Sicherheit-und-Robustheit
Notwendig sind Klärung unternehmensspezifischer, gesetzlicher und ggf. branchenspezifische Anforderungen sowie ein dahingehendes Design und regelmäßige Tests. Die Herausforderung bei der Bereitstellung und Nutzung von APIs ist die verteilte Architektur, die im Gegensatz zur Kommunikation von Modulen innerhalb eines Monolithen zusätzliche Fehlermöglichkeiten wie Timeouts beinhaltet. Im Anforderungsmanagement und Design sind daher eine Analyse aller Fehlermöglichkeiten, messbare SLAs (Antwortzeiten, Timeouts, Durchsatz, …) und eine fachliche sowie technische Reaktion im Fehlerfalle bzw. bei Abweichung von SLAs notwendig. Für die Überwachung der SLAs und Fehlerfälle sind Vorgaben für umzusetzende Inhalte im Logging und Monitoring notwendig.

Lebenszyklus und Versionierung - muss die API-Architektur definieren

API-Architektur-7-Lebenszyklus-und-Versionierung

Bei API-Architektur unterliegt jede Schnittstelle einem Lebenszyklus. Neue Anforderungen bringen Updates mit sich. Hierfür ist eine Strategie notwendig, um die erforderliche Weiterentwicklung mit der Stabilität, die die Schnittstellenpartner zwingend brauchen, in Einklang zu bringen. Es kann dazu erforderlich sein, mehrere unterschiedliche Versionen einer API gleichzeitig anzubieten. Um zu verhindern, dass die Zahl der alten Versionen über Gebühr ansteigt und als Folge sich die Wartung verteuert, gehört auch die Dekommissionierung alter Versionen zum API-Lifecycle-Management.