Skip to main content

API Guidance: Ein Überblick über API-Technologien Teil 2

Application Programming Interfaces (APIs) sind ein wesentlicher Bestandteil moderner verteilter Systeme – und ein wesentliches Glied in der Datenlieferkette für moderne, datengesteuerte Organisationen. Sie sind daher unverzichtbar für das Ökosystem des Datenaustauschs, welches das Support Centre for Datasharing fördern möchte. In dieser dreiteiligen Serie, die von eLearning-Modulen begleitet wird, wollen wir konzentriertes und praktisches Wissen für diejenigen anbieten, die über die Entwicklung und den Einsatz einer API nachdenken und daher die Grundlagen dieser Technologie verstehen müssen, sowie für diejenigen, die mehr Informationen darüber suchen, was bei der Implementierung zu beachten ist.

Dieser Inhalt wird auf zwei Arten veröffentlicht:

  1. Hier als Website-Inhalt in drei Episoden, jeden Monat mit einer neuen Folge, und
  2. nach Abschluss der Serie als einzelnes Dokument, das Sie herunterladen und offline lesen können.

Der Leitfaden ist in Englisch, Französisch und Deutsch verfügbar. Auf jede Ausgabe folgen eLearning-Module, die die jeweiligen Themen abdecken und Ihnen helfen, Ihr Wissen zu testen.

Im ersten Teil dieser Serie haben wir bereits die Grundlagen von APIs behandelt. Die zweite Folge umfasst:

  • API-Typen und deren praktische Umsetzung
  • Anwendungsszenarien
  • API-Dokumentation

In der dritten Folge werden die Implementierungsrichtlinien für APIs erörtert und folgende Schwerpunkte gesetzt:

  • RESTful-Schnittstellen
  • GraphQL-Schnittstellen
  • Sicherheitsdesign
  • API-Dokumentation

Wir freuen uns auf Ihre Kommentare und laden Sie dazu ein, weiterführende Themen in unserem forum zu besprechen.

 

4. API-Typen und ihre praktischen Auswirkungen

Es gibt verschiedene Arten von APIs, mit denen Microservices und eigenständige Systeme miteinander kommunizieren können.Im folgenden Abschnitt werden fünf der wichtigsten API-Typen erläutert: SOAP, RESTful-Schnittstellen, GraphQL, Streams/Ereignisse und Weblinks.

 

4.1 SOAP

Das „Simple Object Access Protocol“ (SOAP oder WS-SOAP) ist ein standardisiertes Protokoll1 für RPCs. RPCs lösen eine Operation zwischen zwei Systemen unter Verwendung des HTTP(S)-Protokolls und der XML-Datendarstellung aus. HTTP(S) dient als zugrunde liegendes Transportprotokoll für den Zugriff auf den Einstiegspunkt eines SOAP-Dienstes. Der Nachrichteninhalt zur tatsächlichen Implementierung des RPC ist in standardisierten XML-Daten enthalten.

SOAP ist immer noch weit verbreitet, hauptsächlich weil es mit den Framework-spezifischen Interoperabilitätsanforderungen vorhandener Anwendungen kompatibel ist, die dem SOA-Ansatz (Service-Oriented Architecture) folgen. Es wird auch dank des riesigen SOAP-Ökosystems aus technischen Komponenten und Implementierungsrichtlinien als vorteilhaft empfunden. Dazu gehören beispielsweise Sicherheitsdienste und verbindliche Technologierichtlinien, die Projekte berücksichtigen sollten.

XML und SOAP sind bis heute sehr präsent und in verschiedenen vorhandenen oder älteren Schnittstellen und Implementierungen implementiert. Es handelt sich aber auch um Schwergewichtstechnologien, die zunehmend durch Anwendungen ersetzt werden, die einen RESTful- oder Microservice-Ansatz verwenden. Dieser API-Leitfaden konzentriert sich auf modernere Ansätze und befasst sich daher nicht eingehender mit SOAP.

 

4.2 RESTful-Schnittstellen

RESTful-Schnittstellen wenden die REST-Architektur (Representational State Transfer) an, um einem Client (d. h. dem anfordernden System) den Zugriff auf und die Bearbeitung der Textdarstellungen von Webressourcen durch vordefinierte, einheitliche und zustandslose Vorgänge zu ermöglichen. REST basiert auf Hypermedia-Links, d. h. auf Links zu anderen Inhalten wie Videos, Audio und Text über Hyperlinks. Obwohl das Paradigma nicht von einem bestimmten Transportprotokoll abhängt, verwenden RESTful-Webservices häufig die festen Operationen des HTTP(S)-Protokolls.

In der Praxis verweist ein RESTful-Link auf eine einzelne oder eine Reihe von Hypermedia-Ressourcen, z. B. Bücher in einem Buchladen:

https://my-bookstore.com/store/books

https://my-bookstore.com/store/books/1

Der erste Link gibt eine Liste aller verfügbaren Bücher zurück, während der zweite Link auf ein bestimmtes Buch verweist. Wie bereits erwähnt, verwenden RESTful-Schnittstellen nicht nur URLs, um auf Einstiegspunkte oder Ressourcen zu verweisen, sondern auch, um zusätzliche Funktionen auszulösen:

https://my-bookstore.com/store/books/1/numberInStock

Dieser Link würde eine Funktion aufrufen, die zählt, wie viele Exemplare eines bestimmten Buches auf Lager sind. Auf die gleiche Weise können Links erweitert werden, um andere Parameter wie Filter oder Abfragen für einen bestimmten Autor zu erfüllen:

https://my-bookstore.com/store/books?author=Doyle

In Kombination mit dem HTTP-Protokoll können diese Links den Vorgang definieren, der für eine Ressource ausgeführt werden soll, z. B.:

GET https://my-bookstore.com/store/books (um eine Liste der Bücher abzurufen)

DELETE https://my-bookstore.com/store/books/1 (um ein bestimmtes Buch zu löschen)

POST https://my-bookstore.com/store/books/1 (um ein Buch in einer bestimmten Liste zu erstellen)

Wenn ein Buch in eine Liste aufgenommen wird, werden die Details des neuen Buches als Nutzdaten im Hauptteil der POST-Anforderung im JSON-Format angegeben:

{

                                           "title":"4.50 From Paddington. (Miss Marple)",

                                           "author":"Agatha Christie",

                                           "isbn":"978-0007120826"

}

Bei der GET-Abfrage ist die Liste der Bücher als Nutzlast im Hauptteil der GET-Antwort enthalten. Ein HTTP-Methodenaufruf wird durch Metadaten ergänzt, die in der Anforderung gesendet und in der Antwort zurückgegeben werden. Solche Metainformationen können das Darstellungsformat sein, das verwendet oder angegeben werden soll, z. B. JSON

Inhaltstyp: application/json

Zusätzlich zu diesen Elementen enthält jede HTTP-Antwort einen Statuscode. Die HTTP-Statuscodes sind meist standardisiert, z. B.

200 OK

Zusammenfassend deckt eine grundlegende REST-Schnittstelle diese fünf Hauptelemente ab:

  1. URL-Schema, einschließlich Parameter
  2. HTTP-Methoden
  3. HTTP-Metadaten
  4. Nutzlast, die durch ein Darstellungsschema definiert wird
  5. Statuscodes

Weitere Aspekte und Ratschläge zum Erstellen einer guten REST-Schnittstelle finden Sie in zahlreichen Handbüchern, z. B. in den HATEOS-Regeln (Hypermedia As Engine of Application State).2 Eine vollständige Schnittstellenspezifikation eines Dienstes sollte anhand einer formalen Beschreibung wie dem Standardvorschlag für OpenAPI 3 definiert werden.3 Die formale Beschreibung und Dokumentation von APIs wird in Abschnitt 6 erläutert.

 

4.3 GraphQL

Während WS-SOAP und WS-REST generische Ansätze für den Datenaustausch und die Kommunikation in verteilten Systemen sind, kann GraphQL dazu beitragen, Daten flexibler und – je nach Anwendungsfall – effektiver abzurufen und zu ändern. Lösungen, die auf WS-SOAP und WS-REST basieren, können in einigen Fällen zu ineffektivem Verhalten führen. Am häufigsten tritt diese Ineffektivität in Form langer Hin- und Rückfahrten sowie in Form von Unter- und Überabruf von Daten auf. Lange Roundtrips beschreiben eine Situation, in der es einfach (relativ) lange dauert, bis der Kreis von Abfrage zu Antwort, d. h. von Client zu Server und zurück zum Client, abgeschlossen ist. Unter- und Überabruf von Daten beschreiben stattdessen Situationen, in denen APIs entweder zu wenig oder zu viele Daten bereitstellen – was parallel auftreten kann. Stellen Sie sich zum Beispiel vor, ein API-Benutzer möchte auf seiner Website eine Liste von Büchern mit Buchtiteln und den jeweiligen Autoren anzeigen, aber die Bücher und Autoren werden in verschiedenen Ressourcen gespeichert und sind über separate API-Endpunkte zugänglich (“https:…/store/books” and “https:…/store/authors”). Der Benutzer würde zuerst die Liste der Bücher vom jeweiligen Endpunkt anfordern, aber zu viele Informationen wie ISBNs (Überabruf) erhalten. Dann müsste der Benutzer auch den anderen Endpunkt aufrufen, um die vollständigen Autorennamen anzufordern (Unterabruf).4 Um diese Probleme zu umgehen, können API-Anbieter ihre APIs optimieren, indem sie Methoden und Problemumgehungen in der Benutzeroberfläche bereitstellen, die für bestimmte Anwendungsfälle geeignet sind. In der Regel gibt es jedoch einfach zu viele Anwendungsfälle, die sich aufgrund neuer oder sich durch neue oder Veränderungen in den Geschäftsfälle ändern können. Daher ist der Workaround-Ansatz weder flexibel genug noch kostengünstig. Trotzdem hat Facebook die GraphQL-API entwickelt, mit der insbesondere Benutzeroberflächen schnell und flexibel angepasst werden können, ohne dass eine API zu oft angepasst werden muss.

GraphQL verwendet HTTP(S), um auf einen Einstiegspunkt zuzugreifen. Der GraphQL-Einstiegspunkt ermöglicht das Abrufen der veröffentlichten Daten mit einer einfachen Abfragesprache. Zunächst müssen Anbieter einer GraphQL-API ein globales Datenschema bereitstellen, das alle Entitäten und Metainformationen enthält. Dies könnte wie folgt aussehen:

type Author {

                                           name:String

                                           address:String

}

 

type Book {

                                           title:String

                                           isbn:String

                                           authors:[Author]

}

 

type Query {

                                           books:[Book]

                                           book(title:String):Book

}

Ein GraphQL-Dienst mit diesem Schema stellt eine Liste mit allen Büchern und ihren Autoren bereit, die folgende Abfrage verwenden:

{ books { title, authors { name } } }

Mithilfe der folgenden Abfrage werden auch die Details eines bestimmten Buches angezeigt:

                             { book(“4.50 From Paddington.(Miss Marple)”) { title, isbn, authors { name } } }

Das GraphQL-Schema definiert die maximale Ansicht der Daten, auf die ein Client über einen GraphQL-Einstiegspunkt zugreifen kann. Nicht alle Felder im Schema müssen echte Datenfelder im zugrunde liegenden Datenspeicher sein. Beispielsweise könnte ein Feld vom Server als Funktion intern implementiert werden, z. B. „numberOfBooks". Durch die Bereitstellung der gesamten verfügbaren Daten für den Client über eine API kann ein Client schnell und sehr flexibel an die Datenansicht angepasst werden, die der Client für einen Anwendungsfall wirklich benötigt. Änderungen an der API sind nur erforderlich, wenn sich das Datenschema ändert. Auch in diesem Fall darf ein Client nur geändert werden, wenn er die geänderten Felder verwendet.

Ein GraphQL-Einstiegspunkt für einen bestimmten Dienst wird als GraphQL-Server implementiert. Der GraphQL Server kennt das angegebene Datenschema und wertet eine GraphQL-Abfrage aus. Der GraphQL Server verwaltet normalerweise nicht die zugrunde liegenden Daten selbst. Stattdessen fungiert er eher als Proxy und ordnet die Abfragen effektiv und effizient einem vorhandenen Datenbankverwaltungssystem oder anderen Quellsystemen zu. Neben der Abfrage der Daten ermöglicht GraphQL auch das Ändern der Daten und das Abonnieren von Nachrichtenströmen, sodass Datenbenutzer sofort über Ereignisse informiert werden können.

Normalerweise gibt es nur einen Einstiegspunkt für GraphQL. Aus Gründen wie dem Datenschutz kann ein Dienst jedoch Einstiegspunkte für verschiedene Rollen haben. Um den Zugriff zu verwalten, würden diese Einstiegspunkte den Zugriff auf bestimmte Schemaentitäten für verschiedene Benutzer einschränken und somit deren Fähigkeit einschränken, Daten abhängig von ihrer Rolle abzurufen.

Um die Entwicklung von Clients zu vereinfachen, bietet GraphQL eine Standardimplementierung eines webbasierten „Spielplatzes", der einfach in einen GraphQL Server integriert werden kann.5 Auf dem Spielplatz können GraphQL-Abfragen interaktiv anhand der bereitgestellten Daten getestet werden.

 

4.4 Streams / Ereignisse

Die einfache sequentielle und transaktionale Verarbeitung von Aufgaben ermöglicht es modernen Anwendungen nicht, reaktiv zu sein. Reaktiv bedeutet, dass eine Anwendung reaktionsschnell, elastisch, belastbar und nachrichtengesteuert sein muss. Laut dem Reactive Manifesto funktionieren reaktive Anwendungen in modernen verteilten Systemen besser, die von einer Vielzahl unterschiedlicher Server oder Maschinen geprägt sind, von Mobiltelefonen bis hin zu großen Servern. Dies wird durch die hohen Benutzererwartungen hinsichtlich kürzester Millisekunden-Antwortzeiten und 100 % Betriebszeit bestimmt.6

Asynchrones Messaging mit einem Ereignisbus und in die Warteschlange gestellten.png

Abbildung 2:Asynchrones Messaging mit einem Ereignisbus und in die Warteschlange gestellten Streams

Neue architektonische Entwürfe, wie ereignisgesteuerte Systeme, zielen darauf ab, diesen Anforderungen gerecht zu werden. Darüber hinaus ermöglichen Paradigmen wie die „Command-Query-Responsibility-Segregation“ (CQRS) verteilten Systemen die Kommunikation über asynchrone Nachrichten. Anstatt mit einer weiteren Verarbeitung zu warten, bis der Client eine Antwort vom Server erhalten hat, können asynchrone Nachrichten es einem Client ermöglichen, allen interessierten Listenern, die derzeit verfügbar sind, ein Ereignis anzukündigen. Solche Nachrichten können in einem Stream in die Warteschlange gestellt werden, um sicherzustellen, dass ein oder alle Teilnehmer jede Nachricht lesen – zumindest zu ihrem Zeitpunkt. Dies ermöglicht eine weitaus effektivere Verteilung der Aufgaben auf mehrere Mitarbeiter. Ähnlich wie bei den Nutzdaten zuvor beschriebener APIs transportieren Ereignisse und Nachrichtenströme Informationen. Neben der Verwendung eines gemeinsamen Dienstes für alle Parteien mit einer genau definierten API für das zugrunde liegende Transportprotokoll ist es daher wichtig, dass das Format der Nachrichten und die Betreffe/Themen der spezifischen Kanäle genau definiert und dokumentiert sind.

 

4.5 Weblinks

Während unterschiedliche Back-End-Technologien häufig gut in Microservices und Container strukturiert sind, kann die Arbeitsteilung für das Front-End ebenso schwierig sein. Ebenso wie das Back-End können Front-End-Frameworks – auch neuere – neue Monolithen hervorrufen. Die technische Lösung besteht darin, die GUI aufzubrechen und wiederverwendbare polyglotte Komponenten zu verwenden, z. B. mithilfe von Webkomponenten und der Erstellung von Micro-Frontends.7 Wenn Sie auf Abbildung 1 zurückblicken, erscheint es unabhängig von einer universellen Implementierung vernünftig, die GUI in Brüche aufzuteilen, insbesondere um vertikalisierte Systeme wie die beschriebenen eigenständigen Systeme zu implementieren. In der Praxis setzt sich diese Sichtweise jedoch gerade erst durch.

Um polyglotte GUI-Systeme zu integrieren, ist es sinnvoll, Weblinks zu verwenden, um zwischen GUI-Teilen (z. B. Micro-Frontends) innerhalb des gesamten GUI-Frontends zu wechseln. Diese Weblinks sind jedoch nicht nur ein Zeiger auf einen Einstiegspunkt. Sie enthalten auch Kontextinformationen, um einen Einstiegspunkt zu aktivieren und die Informationen zu einem bestimmten Element mit einer bestimmten Kennung zu bearbeiten. Unabhängig davon, welches GUI-Framework verwendet wird, sollte es keine Schwierigkeit geben, jeden öffentlichen Weblink mithilfe des internen HTTP-Routers des entsprechenden GUI-Codes dem spezifischen Komponentencode zuzuordnen.

Daher können diese Links als ihre eigene Art von API angesehen werden. Wie bei Back-End-APIs muss die Weblink-basierte API für eine GUI-Komponente alle Einstiegspunkte (HTTP-Adressen) und alle Parameter enthalten, die in den Links enthalten sein können.

eLearning-Modul für Kapital 4

 

5. Anwendungsszenarien

Natürlich sollte sich die Auswahl für einen bestimmten API-Typ an den Anforderungen eines bestimmten Anwendungsfalls orientieren – aber in der Praxis ist dies leichter gesagt als getan. Normalerweise kann mehr als eine API-Technologie verwendet werden – und oft ist es schwierig, die beste Lösung zu identifizieren. Wenn ein Dienst eine GUI zur Verwendung durch Dritte bereitstellt, sollte der Anbieter die Weblinks dieser GUI-Komponenten in einer API detailliert beschreiben.

WS-SOAP und WS-REST sind beide Technologien zum Austausch von Daten und RPC in verteilten Systemen. Da Änderungen an diesen API-Typen kritisch sind und komplizierte Anpassungen in den jeweiligen Ökosystemen auslösen, sollten diese Technologien für „stabile“ Geschäftsanwendungsfälle mit Geschäftslogiken verwendet werden, die über einen langen Zeitraum hinweg festgelegt sind, z. B. regelmäßige Massendatenübertragungen. Da WS-REST-APIs leichter sind, sollten sie für neue APIs verwendet werden, wenn ein System erweitert wird, sowie für die interne Kommunikation von Systemen. Die Verwendung von WS-SOAP sollte für ältere APIs zwischen unabhängigen Organisationen reserviert werden. Aber selbst dann wird WS-SOAP wahrscheinlich noch einige Zeit bestehen bleiben, insbesondere wenn es in Standards verwendet wird.

Wenn Daten speziell für GUI-Komponenten flexibel und agil bereitgestellt werden müssen, sollte GraphQL die erste Wahl sein. Bei der gesamten asynchronen Kommunikation zur Implementierung ereignisgesteuerter Architekturen, Ereignisbeschaffung und CQRS sollten Ereignisse und Streams verwendet werden, insbesondere für interne Anwendungsfälle. Bei öffentlichen APIs sollten Anbieter sorgfältig entscheiden, ob der Publish/Subscribe-Mechanismus von GraphQL ihre Anwendungsfälle erfüllt oder ob die erweiterten Ereignisse und Streams besser geeignet sind.

eLearning-Modul für Kapital 5

 

6. Dokumentation

APIs sind das Verbindungsglied zwischen einem Dienst und seinen Benutzern. Die beste Service-Implementierung unter Verwendung der fortschrittlichsten Technologien und kreativen Lösungen wird letztendlich scheitern, wenn die Dokumentation der APIs von schlechter Qualität und nachlässig ist. Einem Benutzer, d. h. einem Programmierer eines Drittanbieters, muss die Möglichkeit gegeben werden, die API gut zu verstehen, um sie erfolgreich verwenden zu können. Daher ist eine gute, umfassende und verständliche Dokumentation ein wesentlicher Bestandteil jeder API – ebenso wichtig wie die robuste und solide Implementierung des Dienstes selbst.

Hierzu reichen die Dokumentation des Quellcodes und eine Dokumentation der Kommentare im Quellcode nicht aus. Da öffentliche APIs verwendet werden, um verteilte Dienste zu verbinden, die von mehreren Parteien geschrieben wurden, können und werden sich die von ihren Tools verwendeten Programmiersprachen unterscheiden. Daher muss die API eine polyglotte Umgebung unterstützen und sollte daher in neutraler Form angegeben, formalisiert und mit einer eindeutigen Semantik versehen werden. Dies kann durch die Verwendung von Schemadefinitionssprachen wie OpenAPI garantiert werden.8 Diese Schnittstellenbeschreibungssprache eignet sich am besten für REST-APIs, kann jedoch auch für Weblinks, Ereignisse/Streams und GraphQL verwendet werden. Eine OpenAPI-basierte Schnittstellenbeschreibung kann auch verwendet werden, um benutzerfreundliche Dokumentation sowie Code für Server- und Client-Implementierungen zu generieren. Dies kann dazu beitragen, eine konsistente Implementierung und Dokumentation der API zu generieren.

Über die syntaktische, informelle Beschreibung der API hinaus sollte eine Erklärung ihres Verhaltens vorliegen. Dies kann erreicht werden, indem standardisierte Modelle/Diagramme bereitgestellt werden, z. B. mithilfe des „Business Process Model and Notation“9 (BPMN) oder von Sequenzdiagrammen der „Unified Modeling Language“10 (UML). Eine weitere wichtige Beschreibung des Verhaltens sollte durch eine umfassende Reihe von Testfällen implementiert werden, z. B. unter Verwendung eines verhaltensgesteuerten Entwicklungsansatzes für API-Tests.11

 
 
 

Bleiben Sie auf dem Laufenden und vergessen Sie nicht, die Materialien zu besprechen, indem Sie jede Folge kommentieren oder mit Ihren Kollegen in unserem forum darüber reden. Testen Sie Ihr Wissen auch in den eLearning-Modulen der SCDS API Guidance: https://elearningcourses.eudatasharing.eu/de/apiguidance/#/

API Guidance: Ein Überblick über API-Technologien Teil 2
Image credit:
(C) 2020 Support Centre for Data Sharing