zurück zum Artikel

API-Abstraktion zur Beschleunigung des Entwicklungsprozesses

Florian Wendel
API-Abstraktion zur Beschleunigung des Entwicklungsprozesses

Softwareentwickler müssen sich heute der Herausforderung stellen, unzählige externe APIs in ihre Anwendungen einzubinden, um dem Nutzer Mehrwert zu bieten. Da die APIs oft unterschiedlich sind, kann das zum echten Zeitfresser werden. API-Abstraktion verspricht hier Abhilfe, jedoch gibt es unterschiedliche Ansätze.

Egal ob man mobile Anwendungen, Websites, Desktop-Programme oder Servercode schreibt, Entwickler müssen oft mehrere externe APIs anbinden. Die mobile Anwendung soll das Log-in mit einem von vielen sozialen Netzen ermöglichen, eine Website soll Buttons zum Liken und Kommentieren haben, Desktop-Programme sollen Daten bei einem Cloud-Storage-Anbieter sichern – am besten kann sich der Nutzer aussuchen bei welchem – und der Server sendet eine E-Mail nach erfolgreicher Registrierung eines neuen Nutzers. All das erfordert Zugriff auf APIs von Anbietern wie Facebook, Dropbox und SendGrid.

Apps benötigen immer mehr Integrationen über APIs (Abb. 1)

Apps benötigen immer mehr Integrationen über APIs (Abb. 1)

Die meisten Anbieter exponieren ihre Dienste über HTTP-Schnittstellen und stellen oft auch SDKs für verschiedene Plattformen bereit, welche die eigentliche HTTP-Kommunikation kapseln und hinter Funktionen verstecken. Doch bereits die Authentifizierung stellt Entwickler vor Hürden. Will man über die API auf den eigenen Account zugreifen, zum Beispiel bei SMS-Anbietern, reicht es meist, einen API-Schlüssel bei den Anfragen mitzugeben. Möchten Entwickler aber Zugriff auf die Daten des Nutzers bekommen, etwa bei Cloud-Storage-Anbietern, geschieht das meist über OAuth 1.0 und/oder OAuth 2.0.

OAuth 2.0 zeichnet sich im Vergleich zu seinem Vorgänger durch mehr Flexibilität und geringere Komplexität dank HTTPS statt aufwendigem Signierungsprozess aus. Beiden gemein ist, dass sie einer Anwendung erlauben, von ihren Nutzern Zugriff auf deren Daten zu bekommen, ohne dass diese Nutzername und Passwort an die Anwendung geben müssen. Stattdessen authentifiziert sich der Nutzer bei dem Dienst und autorisiert den Zugriff auf seine Daten, worauf der Dienst der Anwendung Zugriff erteilt.

Mehr Infos

Auch wenn OAuth 2.0 die Komplexität verringert und mittlerweile deutlich weiter verbreitet ist als OAuth 1.0, müssen Entwickler den veralteten Standard ebenfalls verstehen, da er auch auf Serverseite noch in verschiedenen Implementierungen anzutreffen ist. Zudem gibt es nach wie vor prominente Dienste wie Twitter, die auf OAuth 1.0 setzen.

Das verbreitetste Konzept zur Strukturierung solcher APIs ist ohne Zweifel REST (Representational State Transfer). Es gibt unter anderem vor, dass Ressourcen strukturiert über URIs (Uniform Resource Identifier) zugreifbar und eindeutig adressierbar sein sollen. Der Zugriff erfolgt üblicherweise über HTTP(S), wobei die Operation auf der Ressource über die HTTP-Methode (GET, POST, PUT, DELETE ...) spezifiziert wird.

Während sich viele APIs auf die Fahne schreiben, "RESTful" zu sein, scheint doch jeder eine leicht andere Vorstellung davon zu haben, wie das konkret aussieht – sicherlich auch, weil REST mehr Paradigma als detaillierter Standard ist. Das macht den Aufbau der APIs uneinheitlich.

Auch bei den Datenformaten gibt es Unterschiede: Hier sind zumeist JSON oder XML gesetzt, wobei JSON als lesbarer und kompakter gilt, während XML etwas "mächtiger" ist. Besonders in der Browserumgebung mit allgegenwärtigem JavaScript spielt JSON seine Stärke aus, lässt es sich doch direkt auf JavaScript-Objekte abbilden. XML hingegen erlaubt von Haus aus Referenzen, selbst zyklische, und beliebige Datentypen. Die Herausforderung für Entwickler ergibt sich, weil manche APIs JSON benutzen und andere XML. Seltener finden sich solche, die wahlweise beides anbieten.

Die eigentlichen Daten, die ein Dienst zurückgibt oder entgegennimmt, unterscheiden sich ebenfalls. Als einfaches Beispiel soll das Geburtsdatum eines Benutzers dienen. So gibt Facebook einen String im Format "MM/DD/YYYY" zurück beziehungsweise "YYYY" oder "MM/DD", wenn die Information nicht vollständig öffentlich ist.

Facebook nutzt ein anderes Format für Datum als andere Anbieter (Abb. 2).

Facebook nutzt ein anderes Format für Datum als andere Anbieter (Abb. 2).

Google+ verwendet "YYYY-MM-DD", und Microsoft Live liefert drei separate Zahlen für Tag, Monat und Jahr. Entwickler kommen also nicht darum herum, sich mit solchen Details auseinanderzusetzen und die Informationen auf das Format zu normalisieren, das sie intern verwenden.

Auch bei der Dokumentation der API bekleckert sich nicht jeder Dienst mit Ruhm. Es gibt Dienste, die sowohl die HTTP-Schnittstelle als auch die SDKs mit ausführlicher Dokumentation versehen, hilfreiche Beispiele inklusive, aber eben auch solche bei denen eine Hand voll Beispiele das Höchste der Gefühle ist und man oft nur durch Recherche oder Ausprobieren dahinter kommt, wie man bestimmte Informationen auslesen oder eingeben kann.

Nicht zuletzt ist zu beachten, dass die Kommunikation mit einer solchen API nicht immer ohne Fehler verläuft. Wenn Nutzer eine ungültige Eingabe machen, können Entwickler zwar abfangen, dass zum Beispiel eine E-Mail-Adresse ein String im korrekten Format ist, nicht aber ohne Weiteres, ob die Adresse wirklich existiert und sich eine E-Mail an diese tatsächlich ausliefern lässt. Es ist deshalb wichtig, die Fehlermeldungen des Servers erkennen und auf die Ausnahmezustände reagieren zu können. Auch hier zeigen sich APIs uneinheitlich. Oft hat der Fehler keine direkte oder nur eine unspezifische Entsprechung in einem HTTP-Statuscode, sodass er oft nur wenig hilfreich ist. Die Fehlerbeschreibung und der maschinenlesbare Code, die entweder im Body oder im Header gesendet werden, sind oft API-spezifisch.

Die genannten Probleme beziehen sich hauptsächlich auf die direkte Interaktion mit der HTTP-API, aber auch beim Benutzen der SDKs der Anbieter haben Entwickler mit den meisten der genannten Unterschiede zu kämpfen.

Da das größte Problem in den Detailunterschieden liegt, selbst bei ähnlichen Diensten, scheint es naheliegend, ähnliche Dienste auf ein gemeinsames Interface zu abstrahieren. Auch ohne Zutun der Dienste kann man so einen Quasistandard schaffen. Je mehr ähnliche Funktionen die Services anbieten, desto mehr lässt sich abstrahieren. Das hat einige Vorteile.

Entwickler müssen sich nicht mehr in jede einzelne Dokumentation einlesen, sondern können sich auf ein Interface konzentrieren. Die Dienste, die das gemeinsame Interface implementieren, können im Code uniform behandelt werden, was ihn kürzer, prägnanter und weniger fehleranfällig macht.

API-Abstraktion über ähnliche APIs (Abb. 3)

API-Abstraktion über ähnliche APIs (Abb. 3)

Auch ist es einfacher, einen Dienst gegen einen anderen auszutauschen, falls der aktuell verwendete an Attraktivität verlieren sollte. Ein Nachteil ist zweifellos, dass Funktionen, über die nur ein spezieller Dienst verfügt, nicht abstrahiert werden können. Wird eine solche verwendet, gehen alle Vorteile der uniformen Behandlung und einfachen Austauschbarkeit verloren. Für Nutzer, die ausschließlich Standardfunktionen nutzen, zum Beispiel Upload und Download bei Cloud-Storage-Anbietern, kann die in der Abstraktion enthaltene Funktionalität jedoch oft ausreichen.

Es gibt mehrere Anbieter solch abstrahierter Integrationen, die sich grob in zwei Arten aufteilen lassen: IPaaS Middleware und abstrahierende SDKs.

Kommerzielle Anbieter wie Kloudless [6] und Cloud-Elements [7] setzen darauf, eine Middleware bereitzustellen, oft unter dem Namen Integration Platform as a Service (IPaaS), die eine uniforme, abstrahierte Schnittstelle zu den Diensten bietet. Wie die Services selbst setzt eine solche IPaaS auf eine HTTP-Schnittstelle und SDKs für diverse Plattformen, um die Schnittstelle einfacher zugreifbar zu machen.

IPaaS-Anbieter nutzen eine externe Middleware (Abb. 4).

IPaaS-Anbieter nutzen eine externe Middleware (Abb. 4).

Ein klarer Vorteil ist, dass Entwickler auf beliebigen Plattformen die Abstraktion nutzen können, denn selbst wenn kein SDK für die eigene Plattform existiert, kann man immer noch direkt mit der HTTP-Schnittstelle interagieren. Leider hat der IPaaS-Ansatz auch einige Nachteile. Zuerst einmal stellt die Middleware einen alleinigen Ausfallpunkt dar. Sind die Server des Anbieters unerreichbar, funktioniert auch keine Integration mehr. Des Weiteren fließen alle Daten zwischen dem Dienst und der eigenen Anwendung über den Server des IPaaS-Anbieters, was besonders bei Cloud-Storage-Diensten unnötigen Datenverkehr und damit einhergehend Kosten verursacht, die an Kunden weitergegeben werden. Nicht zuletzt muss der IPaaS-Anbieter die Daten unverschlüsselt verarbeiten können, wie sonst würde man die vorher erwähnten Geburtsdaten normalisieren. Das stellt ein Problem aus Datenschutzsicht dar, besonders wenn die Server des Anbieters nicht in Deutschland stehen.

Ein alternativer Ansatz zu IPaaS stellen abstrahierende SDKs dar. Sie sind nicht als Middleware auf einem eigenen Server gehostet, sondern direkt als Bibliothek in die Anwendung integriert. Damit sind sie zumindest vonseiten der Hardware nicht anfällig für Ausfälle. Daten lassen sich mit HTTPS verschlüsseln, bevor sie das Gerät verlassen, und es findet kein Umweg statt. Es gibt eine Reihe an Produkten, die diesen Ansatz gehen, zum Beispiel die beiden Open-Source-Projekte Spring Social [8] (für Java-Anwendungen) und HybridAuth [9] (für PHP-Entwickler), aber auch das kommerzielle Produkt CloudRail [10] mit abstrahierenden SDKs für Android, Java, Node.js, Swift und Objective-C. Die meisten fokussieren auf einen bestimmten Aspekt der API-Integration, andere wie das erwähnte CloudRail-Angebot haben etliche weitere Features im Angebot.

API-Abstraktion zur Beschleunigung des Entwicklungsprozesses
Cloud Elements CloudRail HybridAuth Kloudless Spring Social
Technologie Middleware P2P/SDK P2P/SDK Middleware P2P/SDK
Plattformen Alle über API Android, Java, Node.js, Objective-C, Swift PHP Alle über API Java
Kommerziell Ja Ja Nein Ja Nein
API-Kategorien 20 6 1 3 + 2 in Beta 1
API-Update-Prozess Ja Ja Nein Ja Nein

Wer viele APIs integrieren muss, steht vor einer Reihe von Herausforderungen bedingt durch deren Diversität in Authentifizierung, Struktur, Datenformaten, Dokumentation und Fehlermeldungen. Abstraktion kann Abhilfe schaffen, es gibt gehostete Angebote und direkt in die eigene Anwendung integrierbare Bibliotheken. Erstere überzeugen durch Plattformunabhängigkeit, letztere haben Vorteile in Skalierbarkeit, Robustheit und Datenschutz.

Dass sich die API-Anbieter irgendwann auf einen gemeinsamen Standard einigen, der dann auch von allen eingehalten wird, ist unwahrscheinlich. Zu groß ist das Bedürfnis, sich von der Konkurrenz funktional absetzen zu können, wobei Standards eher hinderlich sind. Da zu erwarten steht, dass das Angebot an APIs weiter wächst, gewinnt das Thema "einheitlicher Zugriff" mehr und mehr an Bedeutung, was oben genannte Produkte zunehmend wichtiger werden lässt.

Florian Wendel
ist der CTO des Mannheimer Startups CloudRail. Als einer der Hauptentwickler des CloudRail SDKs hat er sich mit unzähligen APIs auseinandergesetzt und versteht den Aufwand, den das Erstellen und Pflegen von API-Integrationen mit sich bringt.
(ane [11])


URL dieses Artikels:
https://www.heise.de/-3339906

Links in diesem Artikel:
[1] https://www.heise.de/hintergrund/Tipps-und-Tricks-fuer-AngularJS-Teil-3-OAuth-2-0-2620374.html
[2] https://www.heise.de/hintergrund/OpenID-Connect-Login-mit-OAuth-Teil-1-Grundlagen-2218446.html
[3] https://www.heise.de/hintergrund/OpenID-Connect-Login-mit-OAuth-Teil-2-Identity-Federation-und-fortgeschrittene-Themen-2266017.html
[4] https://www.heise.de/ratgeber/Flexible-und-sichere-Internetdienste-mit-OAuth-2-0-2068404.html
[5] https://www.heise.de/ratgeber/Autorisierungsdienste-mit-OAuth-845382.html
[6] https://kloudless.com
[7] http://cloud-elements.com
[8] http://projects.spring.io/spring-social/
[9] http://hybridauth.sourceforge.net/
[10] https://cloudrail.com/
[11] mailto:ane@heise.de