API-Design - Kai Spichale - E-Book

API-Design E-Book

Kai Spichale

0,0

Beschreibung

Application Programming Interfaces (APIs) sind allgegenwärtig, denn Softwareentwickler benutzen sie nicht nur ständig, sondern entwerfen sie häufig auch. Dieses Buch bietet erstmals eine umfassende Anleitung für das vielfältige Thema API-Design. Neben theoretischen Konzepten werden zahlreiche praktische Hinweise und Programmbeispiele für Java-APIs gegeben. Remote APIs in Form von RESTful HTTP, SOAP-Webservices und Messaging, die für moderne Webanwendungen und andere verteilte Systeme enorm wichtig sind, spielen in diesem Buch ebenfalls eine zentrale Rolle. Aus dem Inhalt: - Entwurf leicht benutzbarer APIs - Kompatibilität und Versionierung - Objektkollaboration, Fluent APIs und Thread-Sicherheit - Dokumentation - Skalierbarkeit, Caching - API-ManagementNach der erfolgreichen Lektüre dieses Buches kennen Sie die Grundlagen von APIs und sind in der Lage, objektorientierte APIs für Softwarekomponenten und Remote APIs für verteilte Systeme zu entwerfen. In der zweiten Auflage sind u.a. die Behandlung des API-Standards OData, zusätzliche Informationen über GraphQL, das Jigsaw-Modulsystem von Java und die Metrik Konnaszenz zur Untersuchung der Änderbarkeit von APIs hinzugekommen.

Sie lesen das E-Book in den Legimi-Apps auf:

Android
iOS
von Legimi
zertifizierten E-Readern

Seitenzahl: 436

Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:

Android
iOS
Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Kai Spichale beschäftigt sich seit mehr als 10 Jahren leidenschaftlich mit Softwarearchitekturen von verteilten Systemen und sauberem Code. Nach seinem Studium am Hasso-Plattner-Institut war er u. a. als Softwarearchitekt für die adesso AG und als IT-Berater für innoQ Deutschland GmbH tätig. Als IT Solution Architect arbeitet er heute für SAP SE. Sein technologischer Schwerpunkt liegt auf modernen Architekturansätzen, API-Design und Datenbanktechnologien. Er lebt mit seiner Familie in Berlin.

Zu diesem Buch – sowie zu vielen weiteren dpunkt.büchern – können Sie auch das entsprechende E-Book im PDF-Format herunterladen. Werden Sie dazu einfach Mitglied bei dpunkt.plus+:

www.dpunkt.plus

Kai Spichale

API-Design

Praxishandbuch für Java- undWebservice-Entwickler

2., überarbeitete und erweiterte Auflage

Kai Spichale

[email protected]

Lektorat: René Schönfeldt

Copy-Editing: Ursula Zimpfer, Herrenberg

Satz: Birgit Bäuerlein

Herstellung: Stefanie Weidner

Umschlaggestaltung: Helmut Kraus, www.exclam.de

Druck und Bindung: mediaprint solutions GmbH, 33100 Paderborn

Bibliografische Information der Deutschen Nationalbibliothek

Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.

ISBN:

Print     978-3-86490-611-4

PDF      978-3-96088-602-0

ePub    978-3-96088-603-7

mobi    978-3-96088-604-4

2., überarbeitete und erweiterte Auflage 2019

Copyright © 2019 dpunkt.verlag GmbH

Wieblinger Weg 17

69123 Heidelberg

Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Die Verwendung der Texte und Abbildungen, auch auszugsweise, ist ohne die schriftliche Zustimmung des Verlags urheberrechtswidrig und daher strafbar. Dies gilt insbesondere für die Vervielfältigung, Übersetzung oder die Verwendung in elektronischen Systemen.

Es wird darauf hingewiesen, dass die im Buch verwendeten Soft- und Hardware-Bezeichnungen sowie Markennamen und Produktbezeichnungen der jeweiligen Firmen im Allgemeinen warenzeichen-, marken- oder patentrechtlichem Schutz unterliegen.

Alle Angaben und Programme in diesem Buch wurden mit größter Sorgfalt kontrolliert. Weder Autor noch Verlag können jedoch für Schäden haftbar gemacht werden, die in Zusammenhang mit der Verwendung dieses Buches stehen.

5 4 3 2 1 0

Für Marion und Rudolf

Vorwort

Es gibt bereits sehr gute Bücher über Softwarearchitektur und Design. Warum dann noch dieses Buch über den Entwurf von Application Programming Interfaces, kurz APIs? Weil meiner Meinung nach der Bedarf dafür existiert! Denn API-Design unterscheidet sich von den klassischen objektorientierten Design-Heuristiken, die mit einem internen Datenmodell beginnen und versuchen, Applikationen im Hinblick auf Wartbarkeit und Flexibilität zu optimieren. Im Gegensatz dazu nimmt API-Design die Perspektive der Benutzer, d. h. anderer Entwickler, ein und versucht, die Benutzung von Komponenten oder Diensten durch gutes API-Design für diese Entwickler möglichst einfach zu machen. API-Design ist deswegen nicht nur wichtig für Open-Source-Frameworks, auch unternehmensinterne Softwarekomponenten können davon profitieren. Ein anderer Grund für dieses Buch ist die schnell wachsende Anzahl intern und extern eingesetzter Web-APIs. Deswegen finden Sie in diesem Buch Techniken und Best Practices für Java-, Web- und Messaging-APIs.

Warum ist API-Design wichtig?

APIs gibt es in allen Größen und Formen: Das Spektrum reicht von der Betriebssystem-API POSIX bis zur Web-API des Kurznachrichtendienstes Twitter und von der API der Java-Klassenbibliothek bis zur Web-API des Cloud-Speichers Amazon S3.

APIs sind der Kleber, der unsere digitale Welt zusammenhält.

Als Softwareentwickler arbeiten wir ständig mit ihnen. Aber wir benutzen sie nicht nur, wir schreiben sie auch. Wenn Sie ein Softwareentwickler sind, dann sind Sie auch ein API-Designer. Warum ist das so? Beispielsweise ist eine gute Architektur in Module strukturiert. Jedes dieser Module braucht eine API, über die es aufgerufen werden kann. Die APIs entscheiden darüber, wie einfach oder schwer die Module integriert werden können.

Nützliche Module werden wiederverwendet, sodass deren API nicht nach Belieben verändert werden sollte. Angenommen eine API wird von drei anderen Applikationen verwendet, dann gibt es drei gute Gründe, Kompatibilität bei Änderungen zu berücksichtigen.

APIs können zu den wertvollsten Assets eines Unternehmens gehören.

Mithilfe von APIs können Kunden oder Partner einen Dienst integrieren. Häufig wird deswegen auch die API als das eigentliche Produkt angesehen. Kunden investieren viel Zeit und Geld in die Integration einer API. Die Kosten für einen Umstieg auf eine andere API sind meist sehr hoch. Deswegen werden Kunden durch APIs gebunden. Allein die Twitter-API hat Zehntausende registrierte Applikationen.

APIs können zu den größten Verbindlichkeiten eines Unternehmens gehören.

APIs können nicht nur wertvoll für Unternehmen sein, sie können auch eine Last darstellen. Eine schlechte API oder eine schlechte Dokumentation kann unzählige Supportanfragen zur Folge haben. Aber eine schlechte API kann nicht mal eben verändert werden. Aus diesem Grund erfahren Sie in diesem Buch, was alles beim API-Design zu beachten ist.

Eine Frage der Perspektive

Zweifellos gibt es Softwareentwickler, die APIs korrekt entwickeln, ansonsten gäbe es nicht so viele gute Applikationen, Frameworks und Webservices. Doch es scheint so, als ob die Prinzipien des API-Designs häufig nur unbewusst durch Erfahrung erlernt werden. Softwareentwickler folgen Regeln, ohne sich dessen bewusst zu sein oder deren zugrunde liegende Motive zu kennen.

Beim API-Design geht es um Kommunikation zwischen Entwicklern.

APIs werden nicht für Computer geschrieben, sondern für Menschen. Was bedeutet das? Wir schreiben Software nur in ganz wenigen Ausnahmen in Isolation. Vielmehr baut unsere Software auf existierenden Komponenten und Services auf, deren APIs wir auswählen und verstehen müssen. Weil diese Komponenten und Services von anderen Entwicklern geschrieben wurden, ergibt sich ein Kommunikationsproblem. Denn in den wenigsten Fällen können uns diese Entwickler persönlich erklären, wie die API funktioniert. Daher muss die API selbst der primäre Kommunikationskanal sein. Das kann nur funktionieren, wenn eine API klar, einfach und gut dokumentiert oder sogar selbsterklärend ist.

Können Sie voraussetzen, dass die Benutzer Ihrer API diese bis in letzte Detail verstehen? Das Gegenteil ist oftmals der Fall: Entwickler müssen ihren Job möglichst schnell erledigen. Da bleibt keine Zeit, alles über eine API in Erfahrung zu bringen, bevor man sie benutzt. Entwickler rufen eine Methode der API auf und schauen, was passiert. Wenn das gewünschte Verhalten eintritt, sind sie fertig, ansonsten probieren sie etwas anderes. Entwickler fangen häufig mit Erfahrung an und das Verständnis folgt später, in manchen Fällen nie [Tulach 2008]. Dieses Prinzip der Ahnungslosigkeit ist sogar gewünscht. Denn darum geht es ja gerade bei Modularisierung, Wiederverwendung und dem Geheimnisprinzip. Aus diesem Grund muss eine API intuitiv verständlich sein. Sie sollte keine Überraschungen bereithalten und es Entwicklern schwer machen, sie falsch zu benutzen.

Die Perspektive ist beim API-Design entscheidend. APIs sollten aus der Perspektive ihrer potenziellen Benutzer entworfen werden.

Wer sind die Benutzer? Was wollen sie mit der API machen? Welche Technologien benutzen sie? Das sind Fragen, die API-Designer beantworten müssen, um eine erfolgreiche und gute API zu entwerfen.

Zielgruppe und Voraussetzungen

Dieses Buch richtet sich an Softwareentwickler und -architekten, die APIs für Frameworks, Bibliotheken oder andere Softwarekomponenten entwickeln. Aber prinzipiell ist das in diesem Buch vorgestellte API-Design für jeden Entwickler interessant, der Code schreibt, der von anderen Entwicklern wiederverwendet wird. Zu Beginn des Buches werden allgemeine Konzepte, Qualitätsmerkmale und Vorteile des API-Designs beschrieben. Dann folgen praktische Tipps und Best Practices für Java-Softwarekomponenten. Eine Übertragung auf andere Programmiersprachen ist durchaus möglich, muss aber durch den Leser erfolgen.

Das Buch richtet sich auch an Softwareentwickler und architekten, die Web-APIs entwickeln und dafür REST und HTTP einsetzen. Für mobile Applikationen, IoT-Szenarien, zur Integration von Microservices etc. eignen sich auch Messaging-APIs, die ebenfalls in diesem Buch betrachtet werden. Praktische Erfahrungen mit diesen Technologien sind sicherlich von Vorteil, aber keine zwingende Voraussetzung, denn alle Konzepte und Technologien werden erklärt.

Struktur des Buches

In diesem Buch werden Sie sowohl allgemeine Konzepte als auch konkrete Techniken und Best Practices für unterschiedliche APIs und Protokolle kennenlernen. Aus diesem Grund ist das Buch in vier Teile gegliedert, die wiederum aus mehreren Kapiteln bestehen.

Teil I: Grundlagen

Der erste Teil des Buches umfasst wichtige Grundlagen und besteht aus den Kapiteln 1 bis 3:

Kapitel 1

beginnt mit einem Überblick über die Geschichte der APIs. In diesem Einstieg werden Zweck, Funktion und Bedeutung von APIs beschrieben.

Kapitel 2

stellt die Qualitätsmerkmale vor, die beim API-Design berücksichtigt werden sollten. Diese Merkmale sind die Voraussetzung für alle weiteren Designtechniken in diesem Buch.

Kapitel 3

beschreibt das allgemeine Vorgehen beim Entwurf von APIs. Für den Entwurf werden Beispiele eingesetzt, die zeigen, wie die API von Clients in verschiedenen Szenarien benutzt werden soll.

Teil II: Java-APIs

Nach der allgemeinen Einführung geht es im zweiten Teil um objektorientierte Java-APIs:

Kapitel 4

beschreibt die vielfältigen Ausprägungen von objektorientierten APIs, die man in Bibliotheken, Frameworks und anderen Softwarekomponenten findet.

Kapitel 5

stellt grundlegende Techniken und Best Practices für Java-APIs vor. Hierzu zählen codenahe Themen wie Command/Query Separation, Design für Vererbung, Verwendung von Interfaces und Exception Handling.

Kapitel 6

betrachtet Techniken, die größeren Einfluss auf die Architektur der Anwendung haben, dennoch aber zum API-Design zählen.

Kapitel 7

führt in das Thema Kompatibiliät ein. In diesem Zusammenhang werden theoretische Grundlagen und praktische Techniken vorgestellt.

Teil III: Remote-APIs

An dieser Stelle verlassen wir die Welt der Java-APIs und kommen zu den Remote-APIs, die primär zur Integration unterschiedlicher Systeme eingesetzt werden. Konkret geht es im dritten Teil um RESTful HTTP, SOAP-Webservices und Messaging-APIs:

Kapitel 8

führt in den Architekturstil REST ein und beschreibt dessen Grundprinzipien anhand von RESTful HTTP.

Kapitel 9

stellt Techniken für Web-APIs vor und geht dabei u. a. auf Ressourcendesign, Medientypen und Fehlerbehandlung ein.

Kapitel 10

behandelt Designtechniken für SOAP-Webservices. Dabei werden Granularität, Message Exchange Patterns, Datentypen und Versionierung beschrieben.

Kapitel 11

stellt Messaging als weitere wichtige Alternative zur Integration und Aufrufverarbeitung vor. Neben einem umfassenden Anwendungsbeispiel werden verschiedene Protokolle und Produkte gezeigt.

Teil IV: Übergreifende Themen

Der abschließende vierte Teil des Buches behandelt Querschnittsthemen wie Dokumentation, Skalierbarkeit und API-Management:

Kapitel 12

bietet Empfehlungen zur Dokumentation von APIs. Das Kapitel wird mit der Vorstellung hilfreicher Dokumentationswerkzeuge vervollständigt.

Kapitel 13

behandelt das Thema Caching, das insbesondere für die Performance von RESTful HTTP sehr wichtig sein kann.

Kapitel 14

stellt die Grundlagen skalierbarer Systeme vor. In diesem Zusammenhang werden das CAP-Theorem, statuslose Kommunikation, Load Balancing und verschiedene Architekturvarianten diskutiert.

Kapitel 15

diskutiert Consumer-Driven Contracts, »One size fits all«-APIs und andere Architekturthemen.

Kapitel 16

stellt zu guter Letzt das Thema API-Management vor. Architektur und Werkzeuge für das Veröffentlichen, Dokumentieren und Managen von APIs werden beschrieben.

Pfade durch das Buch

Falls Sie das Buch nicht von Anfang bis Ende lesen wollen, können Sie die Einteilung des Buches nutzen und verschiedene Pfade durch das Buch wählen. Wenn Sie beispielsweise hauptsächlich am Design von Web-APIs auf Basis von RESTful HTTP interessiert sind, können Sie nach den Kapiteln 1 bis 3 direkt mit den Kapiteln 8, 9 und 11 – 15 fortfahren. Falls Sie hingegen an Java-APIs interessiert sind, können Sie nach den Kapiteln 1 bis 7 zum Kapitel 12 springen.

Danksagung

Bei der Arbeit an diesem Buch konne ich von kritischen Diskussionen und wertvollen Kommentaren profitieren. Besonders möchte ich mich bei Eberhard Wolff, Stefan Tilkov, Dirk Ludwig, Ulf Fildebrandt, Ivo Walther und Stefanie Elste bedanken.

Ebenso geht ein Dankeschön an das Team vom dpunkt.verlag. Die Zusammenarbeit mit meinem Lektor René Schönfeldt war stets professionell und freundlich.

Der größte Dank gehört jedoch meiner Frau Ileana, die mich von Anfang an unterstützte und auf viele gemeinsame Abende und Wochenenden verzichten musste.

Bei der Arbeit an der 2. Auflage dieses Buches habe ich von den vielen Hinweisen und Verbesserungsvorschlägen von Anton Schönfeld, Prof. Dr. Dominik Gruntz und Matthias Müller profitiert.

Danke!

Inhaltsübersicht

Teil IGrundlagen

1Application Programming Interfaces – eine Einführung

2Qualitätsmerkmale

3Allgemeines Vorgehen beim API-Design

Teil IIJava-APIs

4Ausprägungen

5Grundlagen für Java-APIs

6Fortgeschrittene Techniken für Java-APIs

7Kompatibilität von Java-APIs

Teil IIIRemote-APIs

8Grundlagen RESTful HTTP

9Techniken für Web-APIs

10SOAP-Webservices

11Messaging

Teil IVÜbergreifende Themen

12Dokumentation

13Caching

14Skalierbarkeit

15Erweiterte Architekturthemen

16API-Management

Anhang

ALiteraturverzeichnis

Index

Inhaltsverzeichnis

Teil IGrundlagen

1Application Programming Interfaces – eine Einführung

1.1Eine kurze Geschichte der APIs

1.2Web-APIs ab dem Jahr 2000

1.3API-Definition

1.4Vorteile einer API

1.5Nachteile einer API

1.6API als Produkt

1.7Welche Strategien verfolgen Unternehmen mit APIs?

1.8Zusammenfassung

2Qualitätsmerkmale

2.1Allgemeine Qualitätsmerkmale

2.2Benutzbarkeit

2.2.1Konsistent

2.2.2Intuitiv verständlich

2.2.3Dokumentiert

2.2.4Einprägsam und leicht zu lernen

2.2.5Lesbaren Code fördernd

2.2.6Schwer falsch zu benutzen

2.2.7Minimal

2.2.8Stabil

2.2.9Einfach erweiterbar

2.3Konnaszenz

2.4Zusammenfassung

3Allgemeines Vorgehen beim API-Design

3.1Überblick

3.2Heuristiken und Trade-offs

3.3Anforderungen herausarbeiten

3.4Wenn Use Cases nicht ausreichen

3.5Entwurf mit Szenarien und Codebeispielen

3.6Spezifikation erstellen

3.7Reviews und Feedback

3.8Wiederverwendung

3.9Zusammenfassung

Teil IIJava-APIs

4Ausprägungen

4.1Implizite Objekt-API

4.2Utility-Bibliothek

4.3Service

4.4Framework

4.5Eine Frage der Priorität

4.6Zusammenfassung

5Grundlagen für Java-APIs

5.1Auswahl passender Namen

5.1.1Klassennamen

5.1.2Methodennamen

5.1.3Parameternamen

5.1.4Ubiquitäre Sprache

5.1.5Fazit

5.2Effektiver Einsatz von Typen

5.2.1Semantischen Vertrag minimieren

5.2.2Semantische Verletzung der Datenkapselung vermeiden

5.2.3Werden Namen überschätzt?

5.2.4Fazit

5.3Techniken für Objektkollaboration

5.3.1Tell, Don’t Ask

5.3.2Command/Query Separation

5.3.3Law of Demeter

5.3.4Platzierung von Methoden

5.3.5Fazit

5.4Jigsaw-Module

5.5Minimale Sichtbarkeit

5.5.1Jigsaw-Module

5.5.2Packages

5.5.3Klassen

5.5.4Methoden

5.5.5Felder

5.5.6Fazit

5.6Optionale Hilfsmethoden

5.6.1Komfort

5.6.2Utility-Klassen

5.6.3Fazit

5.7Optionale Rückgabewerte

5.7.1Ad-hoc-Fehlerbehandlung

5.7.2Null-Objekte

5.7.3Verwendung der Klasse java.util.Optional

5.7.4Fazit

5.8Exceptions

5.8.1Ausnahmesituationen

5.8.2Checked Exception versus Unchecked Exception

5.8.3Passende Abstraktionen

5.8.4Dokumentation von Exceptions

5.8.5Vermeidung von Exceptions

5.8.6Fazit

5.9Objekterzeugung

5.9.1Erzeugungsmuster der GoF

5.9.2Statische Factory-Methode

5.9.3Builder mit Fluent Interface

5.9.4Praktische Anwendung der Erzeugungsmuster

5.9.5Fazit

5.10Vererbung

5.10.1Ansätze zum Einsatz von Vererbung

5.10.2Stolperfallen bei Vererbung

5.10.3Bedeutung für API-Design

5.10.4Fazit

5.11Interfaces

5.11.1Typen nachrüsten

5.11.2Unterstützung für nicht triviale Interfaces

5.11.3Markierungsschnittstellen

5.11.4Funktionale Interfaces

5.11.5Fazit

5.12Zusammenfassung

6Fortgeschrittene Techniken für Java-APIs

6.1Fluent Interface

6.1.1DSL-Grammatik

6.1.2Schachteln versus Verketten

6.1.3Fluent Interface von jOOQ

6.1.4Ist der Aufwand gerechtfertigt?

6.1.5Fazit

6.2Template-Methoden

6.2.1API versus SPI

6.2.2Erweiterbare Parameter

6.2.3Fazit

6.3Callbacks

6.3.1Synchrone Callbacks

6.3.2Asynchrone Callbacks

6.3.3Fazit

6.4Annotationen

6.4.1Auswertung zum Kompilierzeitpunkt

6.4.2Auswertung zur Laufzeit

6.4.3Fazit

6.5Wrapper-Interfaces

6.5.1Proxy

6.5.2Adapter

6.5.3Fassade

6.5.4Fazit

6.6Immutability

6.6.1Wiederverwendung

6.6.2Thread-Sicherheit

6.6.3Einfachheit

6.6.4Umsetzung

6.6.5Automatische Überprüfung mit dem Mutability Detector

6.6.6Codegenerierung mit Immutables

6.6.7Fazit

6.7Thread-sichere APIs

6.7.1Vorteile

6.7.2Nachteile

6.7.3Was bedeutet Thread-Sicherheit?

6.7.4Fazit

6.8Zusammenfassung

7Kompatibilität von Java-APIs

7.1Kompatibilitätsstufen

7.1.1Code-Kompatibilität

7.1.2Binäre Kompatibilität

7.1.3Funktionale Kompatibilität

7.2Verwandtschaftsbeziehungen

7.3Design by Contract

7.4Codeänderungen

7.4.1Package-Änderungen

7.4.2Interface-Änderungen

7.4.3Klassenänderungen

7.4.4Spezialisierung von Rückgabetypen

7.4.5Generalisierung von Parametertypen

7.4.6Generics

7.4.7Ausnahmen

7.4.8Statische Methoden und Konstanten

7.5Praktische Techniken für API-Änderungen

7.6Test Compatibility Kit

7.7Zusammenfassung

Teil IIIRemote-APIs

8Grundlagen RESTful HTTP

8.1REST versus HTTP

8.2REST-Grundprinzipien

8.3Ressourcen – die zentralen Bausteine

8.4HTTP-Methoden

8.5HATEOAS

8.6Zusammenfassung

9Techniken für Web-APIs

9.1Anwendungsbeispiel: Onlineshop

9.2URI-Design

9.3Medientypen

9.4Fehlerbehandlung

9.5Versionierung

9.5.1Daten- und Sprachversionierung

9.5.2Kompatibilität und Perspektive

9.5.3Versionsidentifikation

9.6Sicherheitsmechanismen

9.7Partielle Rückgaben

9.8GraphQL

9.9OData

9.10Zusammenfassung

10SOAP-Webservices

10.1SOAP-Grundlagen

10.2WSDL-Grundlagen

10.3Entwurfsansätze und -muster

10.4Versionierung

10.5SOAP versus REST

10.6Zusammenfassung

11Messaging

11.1Routenplanung für Lkw-Transporte (Teil 1)

11.2Message Broker

11.3Produkte

11.4Standards und Protokolle

11.5Routenplanung für Lkw-Transporte (Teil 2)

11.6Transaktionen und garantierte Nachrichtenzustellung

11.7Asynchrone Verarbeitung und REST

11.8Push Notifications

11.9Zusammenfassung

Teil IVÜbergreifende Themen

12Dokumentation

12.1Motivation

12.2Zielgruppen unterscheiden

12.3Allgemeiner Aufbau

12.4Beispiele

12.5Dokumentation von Java-APIs

12.6Dokumentation von Web-APIs

12.7Zusammenfassung

13Caching

13.1Anwendungsfälle

13.2Performance-Vorteil

13.3Verdrängungsstrategien

13.4Cache-Strategien für Schreibzugriffe

13.5Cache-Topologien für Webanwendungen

13.6HTTP-Caching

13.7Zusammenfassung

14Skalierbarkeit

14.1Anwendungsfall

14.2Grundlagen

14.3Load Balancing

14.4Statuslose Kommunikation

14.5Skalierung von Datenbanken

14.6Skalierung von Messaging-Systemen

14.7Architekturvarianten

14.8Zusammenfassung

15Erweiterte Architekturthemen

15.1Consumer-Driven Contracts

15.2Backends for Frontends

15.3Vernachlässigte Frontend-Architektur

15.4Netflix-APIs

15.5Zusammenfassung

16API-Management

16.1Überblick

16.2Funktionen einer API-Management-Plattform

16.3API-Management-Architektur

16.4Open-Source-Gateways

16.5Zusammenfassung

Anhang

ALiteraturverzeichnis

Index

Teil I

Grundlagen

1Application Programming Interfaces – eine Einführung

APIs sind keine Erfindung der letzten Jahre, denn ihre zugrunde liegenden Prinzipien wurden bereits Mitte des 20. Jahrhunderts erkannt und seitdem in vielfältigen Ausprägungen angewandt. Ab der Jahrtausendwende entstanden zunehmend Web-APIs und eine ganze API-Industrie für E-Commerce, soziale Medien, Cloud und Mobile entwickelte sich. In diesem Kapitel werden wir uns zunächst mit der Entwicklung der ersten APIs beschäftigen, eine Definition finden und die Vorteile von APIs erläutern.

1.1Eine kurze Geschichte der APIs

Das Konzept einer Subroutinen-Bibliothek wird erstmalig 1948 von Herman Goldstine und John von Neumann beschrieben [Goldstine & von Neumann 1948]. Demnach ist die Idee, dass die meisten Programme allgemeine Operationen wiederverwenden, um den Umfang von neuem Code und Fehlern zu reduzieren, nach Informatikermaßstäben schon sehr alt. Für die Idee der Subroutinen-Bibliotheken wurde Maurice Vincent Wilkes 1967 sogar mit dem Turing Award ausgezeichnet.

Wilkes und sein Team bauten den EDSAC-Röhrencomputer, der erstmals die Von-Neumann-Architektur implementierte und gespeicherte Programme ausführte. Wilkes damaliger Ph.D.-Student David Wheeler entwickelte für EDSAC ein detailliertes Schema zum Einsatz von Subroutinen. Während Goldstine und von Neumann vorsahen, das gesamte Programm in den Speicher zu laden und die Adressen vor Ausführung mit einer speziellen Routine zu ändern, entwickelte Wheeler eine Reihe von Initiierungsbefehlen, die zuerst ausgeführt wurden, um ein Programm von Lochkarten einzulesen und ohne weitere manuelle Eingriffe auszuführen. Die Initiierungsbefehle von Wheeler waren eine Art Boot Loader für die Programme auf den Lochkarten. Die Programme wurden in Assembler geschrieben, sodass die Benutzer des Computers nie mit dem Binärcode des Computers zu tun hatten.

Der technische Bericht »The preparation of programs for an electronic digital computer«, den das Team 1951 veröffentlichte, war ein Standardwerk der Programmierung, bis Jahre später die ersten höheren Programmiersprachen folgten. Wheeler veröffentlichte 1952 auf nur zwei Seiten folgende grundlegende Konzepte [Wheeler 1952]:

Subroutinen

Subroutinen-Bibliotheken

Bedeutung von Dokumentation für Subroutinen-Bibliotheken

Geheimnisprinzip

Trade-off zwischen Generalität und Performance

Funktionen höherer Ordnung

Debugger

Routinen zur Interpretierung von Pseudocode

In diesem Dokument schreibt Wheeler, dass die Vorbereitungen für eine Subroutinen-Bibliothek größer sind als ihre eigentliche Programmierung. Außerdem betont er die Bedeutung von Dokumentation von Subroutinen-Bibliotheken. Im abschließenden Fazit nennt er einfache Benutzung, Korrektheit und akkurate Dokumentation als Hauptziele bei der Konstruktion von Bibliotheken. Komplexität sollte vor Benutzern verborgen bleiben.

Obwohl Wheeler schon die Prinzipien der späteren APIs erkannte, unterschied er nicht zwischen API und Implementierung, denn es gab zu diesem Zeitpunkt nur eine Maschinenarchitektur und keine alternativen Implementierungen der Bibliotheken. Erst als die Bibliotheken wegen neuerer Hardware oder wegen besserer Algorithmen neu implementiert wurden und man existierende Programme portieren wollte, gab es Gründe, zwischen API und Implementierung zu unterscheiden.

1968 erschien erstmalig der Begriff »Application Programming Interface« [Cotton & Greatorex 1968]. API und Implementierung werden konzeptionell voneinander getrennt, um Implementierungen austauschen zu können, ohne dass Clients davon betroffen sind.

Mehr als ein halbes Jahrhundert nach Wheelers Pionierarbeit sind seine Aussagen immer noch gültig. Lediglich die Begriffe haben sich verändert. So schreibt Joshua Bloch [Bloch 2006], dass es einfach sein sollte, eine API korrekt zu benutzen, und dass es schwer sein sollte, eine API falsch zu benutzen. Egal wie gut eine API ist, ohne gute Dokumentation wird sie nicht benutzt.

1.2Web-APIs ab dem Jahr 2000

Zur Jahrtausendwende begann die Suche nach innovativen Lösungen, um Produkte mehrerer E-Commerce-Webseiten miteinander zu verbinden. Web-APIs auf Basis der existierenden HTTP-Infrastruktur schienen das richtige Werkzeug für diese Aufgabe zu sein:

Erste XML-APIs von Salesforce.com

Im Februar 2000 startete

Salesforce.com

offiziell eine web-basierte Sales Force Automation für Unternehmen. Dieser Internetdienst setzte von Anfang an XML-APIs ein.

Salesforce.com

reagierte damit auf den Kundenbedarf, Informationen zwischen verschiedenen Geschäftsanwendungen austauschen zu wollen.

Pionierarbeit von eBay

Im November 2000, also nur 7 Monate nach

Salesforce.com

, ging die eBay-API zusammen mit dem eBay Developers Program live. Die eBay-API war eine Reaktion des Unternehmens auf die wachsende Anzahl an Applikationen, die bereits die eBay-Webseite benutzten. Die API sollte die Integration mit diesen und zukünftigen Applikationen vereinheitlichen. eBay kann deswegen als führender Pionier der Web-APIs und Webservices angesehen werden.

Soziale Medien

Neben diesen E-Commerce-Plattformen spielten auch soziale Medien eine wichtige Rolle in der Geschichte der Web-APIs. 2003 startete

del.icio.us

, ein Bookmarking-Dienst zum Speichern, Teilen und Auffinden von Bookmarks für Webseiten. Mit einem leicht verständlichen URL-Schema

1

konnte man eine Liste mit Bookmarks für ein Schlüsselwort abrufen. Diese API war nahtlos in die Webseite integriert.

Del.icio.us

war eine der ersten Webseiten, die HTML zusammen mit maschinenlesbaren Inhalten wie RSS und XML anbot.

Web 2.0

2004 startete Flickr sein Webportal zum Hochladen, Kommentieren und Teilen von Bildern und kurzen Videos. Die Einführung einer RESTful API half Flickr, schnell populär für Blogger und Benutzer sozialer Medien zu werden. Flickr etablierte für Anwendungsentwickler zur Benutzung der API ein Self-Service. Neben seiner technischen Funktion wurde die API ein wichtiger Faktor für die weitere Geschäftsentwicklung. Die moderne Plattform von Flickr zählte zu den typischen Vertretern des »Web 2.0«.

Facebook REST-API

Die Entwicklungsplattform und API von Facebook ist seit 2006 verfügbar. Seitdem ist es Softwareentwicklern möglich, auf Facebook-Freunde, Fotos und Profilinformationen zuzugreifen. Die REST-API war ein Vorteil von Facebook gegenüber Konkurrenten wie MySpace.

Twitter REST-API

Im gleichen Jahr startete auch Twitter seine API auf Basis von REST mit JSON und XML. Wie eBay wollte Twitter auf die wachsende Anzahl an Applikationen reagieren. Die Twitter-API wird von unzähligen Desktop-Clients, mobilen Anwendungen und sogar Geschäftsanwendungen verwendet.

Google Maps API

Ebenfalls 2006 startete Google seine Google Maps API für die zahllosen Entwickler, die Google Maps in ihre Anwendungen integrieren wollten. Dies war die Geburtsstunde der Mashups, die neue Inhalte durch die Kombination bereits bestehender Inhalte erzeugen. Hierfür nutzen Mashups offene APIs, die von anderen Webanwendungen zur Verfügung gestellt werden.

API-Serviceprovider

Die Liste bekannter Web-APIs ließe sich leicht fortsetzen. Wichtig sind ebenfalls die API-Serviceprovider wie Mashery. Dies war 2006 der erste Anbieter einer Infrastruktur zur Entwicklung, Veröffentlichung und Verwaltung von APIs, die es externen Entwicklern ermöglicht, Inhalte anderer Unternehmen für ihre Produkte zu nutzen.

Public Cloud PaaS

In diesem Zeitraum begann außerdem die Ära des Public Cloud Computing Platform as a Service durch die Veröffentlichung der Amazon Web Services (AWS). Amazon startete mit dem Cloud-Speicher Amazon S3 und legte mit Amazon EC2, einem Webservice für die Bereitstellung von skalierbarer Rechenkapazität, nach. Beide bieten eine Web-API. PaaS sollte ein wichtiger Motor der API-Industrie werden.

Mobile Apps

Foursquare startete 2009 einen standortgebundenen Dienst für mobile Geräte, mit dem Benutzer interessante Orte einer Stadt finden können. 2011 folgte die offizielle API von Instagram. APIs entwickelten sich vom Antreiber für E-Commerce-Anwendungen, sozialer Medien und Cloud Computing zum Lieferanten von Ressourcen und Funktionen für mobile Geräte.

Versionierung

Viele APIs leben sehr lang und werden deswegen versioniert. Die Twitter-API v1, die 2006 online ging, wurde beispielsweise erst 2013 eingestellt. Zuvor gab es bereits eine neuere Version der API, sodass Entwickler ausreichend Zeit hatten, ihre Anwendungen umzustellen. Manche APIs leben sogar ewig. Denn aus der Java-Standardbibliothek wurden bisher keine Elemente entfernt, sondern nur als veraltet markiert.

Internet der Dinge

Das nächste große Kapitel der API-Geschichte trägt den Titel »Internet der Dinge« (Internet of Things – IoT). Hinter diesem Trend steckt die Idee, unterschiedlichste intelligente Geräte zu vernetzen, um Menschen bei ihren Tätigkeiten zu unterstützen. Das Spektrum dieser intelligenten Geräte reicht von Kühlschränken bis zu Autos. Mithilfe verschiedener APIs kann man auf die IoT-Einheiten zugreifen. Dies geschieht häufig drahtlos per Wi-Fi, BLE (Bluetooth Low Energy) oder NFC (Near Field Communication). Beispiele sind ThingSpeak, eine Open-Source-Lösung, mit der Entwickler unter Zuhilfenahme von Webtechnologien mit Geräten interagieren können, und OGC SensorThings API, ein Standard zum einheitlichen Zugriff auf IoT-Einheiten, Daten und Applikationen über das Web.

1.3API-Definition

Eine API kann man allgemein definieren als ein Programmteil, das von einem Softwaresystem anderen zur Anbindung zur Verfügung gestellt wird [Wikipedia 2016]. Diese Definition betont korrekterweise den Integrationszweck einer API. Eine API beschreibt aber auch die möglichen Interaktionen, mit denen sie verwendet werden kann. Deswegen gehört zu einer API eine detaillierte Dokumentation der Schnittstellenfunktionen mit ihren Parametern. Laut Martin Reddy [Reddy 2011] bietet eine API eine Abstraktion für ein Problem und spezifiziert, wie Benutzer mithilfe von Softwarekomponenten, die eine Lösung für das Problem implementieren, interagieren sollten.

Allgemeine API-Definition

Eine andere Definition, die wir auch für dieses Buch verwenden wollen, stammt von Joshua Bloch: »Eine API spezifiziert die Operationen sowie die Ein- und Ausgaben einer Softwarekomponente. Ihr Hauptzweck besteht darin, eine Menge an Funktionen unabhängig von ihrer Implementierung zu definieren, sodass die Implementierung variieren kann, ohne die Benutzer der Softwarekomponente zu beeinträchtigen« [Bloch 2014].

API-Typen in diesem Buch

Diese allgemeine Definition verdeutlicht, dass »API« nur der Oberbegriff für viele unterschiedliche API-Spielarten ist. Konkret unterscheidet dieses Buch zwischen Programmiersprachen-APIs und Remote-APIs:

Programmiersprachen-APIs werden beispielsweise von Bibliotheken angeboten und sind sprach- und plattformabhängig. Als Vertreter der Programmiersprachen-APIs behandelt das Buch objektorientierte Java-APIs.

Auf der Seite der Remote-APIs bietet das Buch RESTful HTTP, SOAP-Webservices und Messaging-APIs. Diese APIs sind durch Protokolle wie HTTP sprach- und plattformunabhängig. Diese Eigenschaften erfüllen ebenfalls SOAP-Webservices, die mit und ohne HTTP (z. B. über eine Message Queue) genutzt werden können. Messaging-APIs bieten asynchrone Kommunikation auf Protokollen wie AMQP (Advanced Message Queuing Protocol) oder MQTT (Message Queue Telemetry Transport). Darüber hinaus gibt es auch Remote Procedure Calls (RPCs) und dateibasierte APIs für Konfigurationen und asynchronen Informationsaustausch.

Abb. 1–1Es gibt verschiedene API-Typen. In diesem Buch werden objektorientierte Java-APIs, Web-APIs und Messaging-APIs behandelt.

Service Provider Interface

Auch Frameworks haben eine API, über die sie benutzt und erweitert werden können. Ein Service Provider Interface (SPI) ist eine API, die dazu bestimmt ist, von einem Benutzer erweitert oder implementiert zu werden. Auf diese Weise kann eine Applikation oder ein Framework Erweiterungspunkte bereitstellen. Generell ist für Programmiersprachen-APIs das Thema Vererbung wichtig.

API versus Protokoll

Häufig werden APIs und Protokolle im gleichen Kontext verwendet. Dennoch können und sollten die Begriffe voneinander getrennt werden.

Eine objektorientierte API kann ein Protokoll kapseln. Ein Beispiel dazu ist im Java-Umfeld RMI (Remote Method Invocation). Eine Implementierung dieser Java-API nutzt intern das Protokoll JRMP (Java Remote Method Protocol) für entfernte Aufrufe zwischen Objekten. Ein anderes Beispiel ist JMS (Java Messaging Service). Diese Java-API für Message Queues wird von einem JMS-Provider (z. B. ActiveMQ) mithilfe eines zugrunde liegenden Protokolls (z. B. AMQP) umgesetzt. Eine API-Implementierung kann demzufolge ein Protokoll kapseln bzw. es implementieren. Umgekehrt gilt das nicht: Ein Protokoll kann keine API kapseln oder implementieren.

HTTP ist ein Protokoll, das ist unstrittig, aber HTTP allein stellt noch keine API dar. Eine API kann man jedoch als eine Menge von HTTP-Requests und -Responses inklusive der Struktur der verwendenten Nachrichten definieren. Häufig spricht man in diesem Fall von einer Web-API oder allgemein von einer Remote-API.

Ein anderes anschauliches Beispiel sind WebSockets, weil hier Protokoll und API konsequent voneinander getrennt sind. Das Web-Socket-Protokoll ist in RFC 6455 [Fette & Melnikov 2011] standardisiert und spezifiziert u. a. das Öffnen und Schließen von Verbindungen mit Handshake. Die WebSocket-API [Hickson 2011] definiert u. a. ein WebSocket-Interface mit den Methoden send und close. Mithilfe der API können Webseiten das WebSocket-Protokoll für die Zwei-Wege-Kommunikation mit einem entfernten Host nutzen. Moderne Webbrowser exponieren die API und nutzen das Protokoll zur Kommunikation mit entfernten Servern, die das Protokoll möglicherweise hinter einer serverseitigen API anbinden.

1.4Vorteile einer API

In der zuvor betrachteten kurzen Geschichte der APIs wurden bereits einige Vorteile beschrieben. Ein wichtiger Vorteil, der sich durch die Trennung zwischen API und Implementierung ergibt, ist die Änderbarkeit oder Austauschbarkeit der Implementierung. Solange der Vertrag der API eingehalten wird, müssen Benutzer ihren Code nicht anpassen. Aus diesem Ansatz ergeben sich mehrere Vorteile:

Stabilität durch lose Kopplung

Angenommen Benutzer einer Softwarekomponente wären direkt von den Implementierungsdetails der Softwarekomponente abhängig, dann wäre der Code des Benutzers instabil, weil dieser schon bei kleinen Änderungen der Softwarekomponente angepasst werden müsste. Diese starke Kopplung zwischen einer Softwarekomponente und ihren Benutzern kann durch eine API minimiert werden. Falls beispielsweise ein Webservice seine Ein-Server-Lösung durch eine Lösung mit verteilter Architektur ersetzen muss, weil die Benutzeranzahl wächst und Performance-Probleme auftreten, sollte die Änderung keine Auswirkungen auf bestehende Benutzer haben, obwohl die neue Lösung auf einer völlig anderen Architektur basiert.

Portabilität

Beispielsweise kann ein in ANSI C geschriebenes Programm auf verschiedenen Computerarchitekturen und Betriebssystemen ausgeführt werden, sofern eine konforme C-Implementierung vorhanden ist. Als Beispiel könnte man auch die Java Runtime Environment (JRE) nennen, denn sie bietet für Java-Programme eine einheitliche API-Implementierung für verschiedene Betriebssysteme.

Komplexitätsreduktion durch Modularisierung

Eine API bietet eine geeignete Abstraktion und versteckt die Komplexität der Implementierung. Diese nicht notwendige Kenntnis des API-Benutzers über Implementierungsdetails folgt dem Geheimnisprinzip und hilft, die Komplexität großer Anwendungen zu beherrschen. Die Modularisierung hat wiederum Vorteile für Arbeitsteilung und Entwicklungskosten.

Softwarewiederverwendu ng und Integration

Eine API wird nicht nur entworfen, um Implementierungsdetails zu verbergen, sondern um Funktionen einer Softwarekomponente anderen Entwicklern möglichst einfach zur Verfügung zu stellen. Aus diesem Grund sollte eine API für einfache Wiederverwendung und Integration optimiert werden. Mit RESTful HTTP kann beispielsweise eine einheitliche Schnittstelle für unterschiedliche WebAPIs realisiert werden.

Grundvoraussetzung für die genannten Vorteile ist gutes API-Design. Allerdings ist es gar nicht so einfach, gute APIs zu entwerfen. Das Entwerfen schlechter APIs geht vergleichsweise einfach [Henning 2007]. Eine gute API erkennt man sofort, sobald man sie verwendet: Ihre Benutzung macht Spaß und es gibt kaum Reibungsverluste, weil sie intuitiv benutzbar und gut dokumentiert ist.

Die Konsequenzen schlechten API-Designs sind vielfältig und schwerwiegend: Schlechte APIs sind schwer zu benutzen, und in manchen Fällen muss zusätzlicher Clientcode geschrieben werden, der Programme größer, komplizierter und schwerer wartbar macht. Entwickler brauchen mehr Zeit, um schlechte APIs zu verstehen und zu benutzen. Schlechte APIs führen deswegen zu erhöhten Entwicklungskosten oder zur völligen Ablehnung von Softwarekomponenten, falls Entwickler zwischen mehreren Alternativen wählen können.

1.5Nachteile einer API

Interoperabilität

Eine API hat sicherlich nicht nur Vorteile, sondern auch Nachteile. Erwähnenswert ist die fehlende Interoperabilität von Programmiersprachen-APIs, denn eine Java-API kann beispielsweise nicht von einer Go-Applikation konsumiert werden. Die Lösung liegt allerdings auf der Hand: Die gewünschte Interoperabilität bieten Remote-APIs auf Basis von Protokollen wie HTTP und AMQP, weil diese von unterschiedlichen Plattformen und Programmiersprachen genutzt werden können.

Änderbarkeit

Ein anderer Nachteil, der im Alltag Kopfschmerzen bereiten kann, ist die eingeschränkte Änderbarkeit von APIs, denn die mit den API-Benutzern geschlossenen API-Verträge dürfen nicht gebrochen werden – oder etwa doch?

Um das Problem besser erläutern zu können, sollte man zwischen interner und veröffentlichter API unterscheiden. Letztere hat Benutzer, die Sie nicht kennen oder die Sie nicht kontrollieren. In diesem Fall dürfen Sie keine Änderungen machen, die den bestehenden API-Vertrag brechen. Für die internen APIs ist die Situation anders: Wenn Sie zum Beispiel Ihre Codebasis in Module mit öffentlichen und privaten Teilen strukturieren, erfolgt die Kommunikation der Module untereinander über deren öffentliche Teile, also über deren APIs. In diesem Fall könne Sie die APIs ändern und von Refactoring profitieren, weil Sie den von den APIs abhängigen Code kontrollieren. Generell sollten Sie so wenig wie möglich veröffentlichen, um Änderungen machen zu können.

1.6API als Produkt

Die bisher genannten Funktionen sind hauptsächlich technischer Art. Es gibt jedoch auch wirtschaftliche Funktionen, die wir hier nicht vergessen dürfen. Prinzipiell kann man in diesem Zusammenhang zwischen zwei Unternehmenstypen unterscheiden:

Das Unternehmen ist die API.

Für Unternehmen wie Yelp, Twilio oder SendGrid ist die API das Hauptprodukt. Das Bereitstellen einer nützlichen und leicht verwendbaren API ist ihre Geschäftsgrundlage.

Die API als zusätzlicher Kanal

Für andere Unternehmen wie FedEx, Walmart und Best Buy steht die API weniger im Mittelpunkt. Viele Offline-Unternehmen nutzen APIs, um ihren Markt zu vergrößern.

1.7Welche Strategien verfolgen Unternehmen mit APIs?

Web-APIs können für Unternehmen von strategischer Bedeutung sein. Einige dieser Strategien sind hier aufgezählt:

Mobile Strategie

Unternehmen wie Facebook können nicht für jedes mobile Gerät einen dedizierten Client bauen. Stattdessen setzen sie eine neutrale API ein, die ausfallsicher und skalierbar ist.

Benutzung der Plattform antreiben

Twitter konnte die Benutzung seiner Plattform durch eine besonders gute API steigern. Denn diese API war die Grundvoraussetzung für die vielen Twitter-Apps, mit denen Twitter auf unzähligen Geräten überall und jederzeit genutzt werden kann.

Investition in neue Geschäftszweige

Eine API-Strategie kann der Anfang eines neuen Geschäftszweigs sein und Wachstum zur Folge haben. Auch Best Buy startete eine API zur Steigerung seines Onlinehandels. Schnell entstanden Apps zum Preisvergleich, zum Stöbern im Warenkatalog und zur Verbreitung von Angeboten.

Integration mit Partnern

APIs sind wichtig zur Vernetzung mit Partnern und Zulieferern. Beispielsweise verfolgt FedEx eine API-Strategie, durch die unzählige FedEx-kompatible Applikationen entstanden sind.

Integration innerhalb eines Unternehmens

APIs dienen nicht nur zur Integration von Fremdsystemen, sondern auch innerhalb eines Unternehmens sind sie zur Integration von Systemen wichtig.

1.8Zusammenfassung

In diesem Kapitel haben Sie einen Überblick über die Geschichte der APIs bekommen. Hier sind die wichtigsten Etappen kurz zusammengefasst:

Die ersten Subroutinen-Bibliotheken gab es 1949/1950 für den Supercomputer EDSAC.

Der Begriff »API« wurde 1968 erstmals erwähnt.

Ab 2000 entstehen erste Web-APIs für E-Commerce. Daraufhin entwickelt sich eine ganze API-Industrie für soziale Medien, Cloud Computing, mobile Applikationen und schließlich das Internet der Dinge.

In diesem Kapitel wurden ebenfalls wichtige Vorteile von APIs vorgestellt:

Man kann konzeptionell zwischen einer API und ihrer Implementierung unterscheiden. Eine API bildet den Vertrag und die Beschreibung einer Softwarekomponente.

Eine gute API ist für einfache Wiederverwendung und Integration optimiert.

Das nächste Kapitel geht der Frage nach, was eine gute API ausmacht. Dazu werden Sie verschiedene Qualitätsmerkmale kennenlernen.

2Qualitätsmerkmale

Nachdem Sie im vorherigen Kapitel die Prinzipien und den Zweck von APIs kennengelernt haben, geht es in diesem Kapitel weiter mit den allgemeinen Qualitätsmerkmalen. Diese Merkmale sind das Ziel der Best Practices und Design-Heuristiken in diesem Buch.

2.1Allgemeine Qualitätsmerkmale

Um die Qualität eines Produktes oder einer Applikation bewerten zu können, gibt es viele Qualitätsmodelle, von denen sich insbesondere DIN/ISO 9126 in der Praxis durchgesetzt hat. Die darin definierten Qualitätsziele gelten für Software im Allgemeinen und damit auch für APIs. Ein Ziel ist beispielsweise die Richtigkeit der geforderten Funktionalität. Zweifellos ist das ein wichtiges Ziel, doch welche Ziele kann man für APIs besonders hervorheben?

Benutzbarkeit

APIs sollen für andere Entwickler leicht verständlich, erlernbar und benutzbar sein. Gute Benutzbarkeit ist ein zentrales Ziel beim API-Design, deshalb finden Sie in diesem Kapitel weitere Informationen darüber.

Effizienz

Insbesondere für mobile Applikationen ist geringer Akku-Verbrauch und geringes Online-Datenvolumen wichtig. Remote-APIs und eventuell dazugehörige Software Development Kits (SDKs), mit denen die Remote-APIs aufgerufen werden, sollten dies berücksichtigen. Auch Skalierbarkeit kann ein wichtiges Ziel sein, falls Sie beispielsweise davon ausgehen, dass Ihre API in Zukunft immer häufiger aufgerufen wird.

Kapitel 14

bietet weitere Informationen zu diesem Thema.

Zuverlässigkeit

Die Reife einer API-Implementierung hängt von der Versagenshäufigkeit durch Fehlerzustände ab. Interessant für API-Designer ist vor allem die Frage, wie man mit Fehlern umgehen soll. Informationen über Exception Handling und zur Fehlerbehandlung von Web-APIs finden Sie in

Abschnitt 5.8

und

9.4

.

2.2Benutzbarkeit

Wann ist eine API gut benutzbar? Vermutlich kann diese Frage nur mit einer subjektiven Einschätzung beantwortet werden. Dennoch gibt es eine Reihe allgemein akzeptierter Eigenschaften. Weil aber diese Eigenschaften in der Praxis nie vollständig umgesetzt werden können, könnte man auch von Zielen sprechen:

Konsistent

Intuitiv verständlich

Dokumentiert

Einprägsam und leicht zu lernen

Lesbaren Code fördernd

Schwer falsch zu benutzen

Minimal

Stabil

Einfach erweiterbar

Diese Eigenschaften werden in den folgenen Abschnitten vorgestellt.

2.2.1Konsistent

Kohärentes Design mit der Handschrift eines Architekten

»Konsistenz« deckt sich weitestgehend mit »konzeptioneller Integrität«. Dieses Grundprinzip besagt, dass komplexe Systeme ein kohärentes Design mit der Handschrift eines Architekten haben sollten. Dieses Designprinzip stammt von Frederick Brooks, der bereits vor mehreren Jahrzehnten schrieb: »Konzeptionelle Geschlossenheit ist der Dreh- und Angelpunkt für die Qualität eines Produkts [...]« [Brooks 2008]. Er meint damit, dass Entwurfsentscheidungen, wie beispielsweise Namensgebungen und die Verwendung von Mustern für ähnliche Aufgaben, im gesamten System durchgängig angewandt werden sollen. Das folgende Beispiel soll diese Aussage verdeutlichen. Zu sehen sind zwei Listen mit Funktionsnamen [Lacker 2013]:

str_repeat strcmp

str_split strlen

str_word_count strrev

Die Liste auf der linken Seite beginnt mit einem Präfix »str«. Darauf folgen die Funktionsbezeichnungen, wobei die einzelnen Wörter durch Unterstriche voneinander getrennt sind. Die Funktionsnamen auf der rechten Seite sind ähnlich aufgebaut. Der Unterschied ist, dass man hier auf die Unterstriche verzichtet hat. Vermutlich haben Sie schon erkannt, dass es sich hierbei um die Bezeichnungen von Funktionen zur Bearbeitung von Zeichenketten handelt. Beide Namenskonventionen sind in Ordnung. Es ist eine Frage des persönlichen Geschmacks, welche man bevorzugt.

Was ist das Problem? Das Problem ist, dass beide Namenskonventionen zur gleichen PHP-API gehören. Das bedeutet, dass sich Entwickler nicht nur die Namen der Funktionen, sondern auch ihre Namenskonvention merken müssen. Aus diesem Grund sollte eine API unbedingt die (nur eine) Handschrift eines Architekten1 tragen.

Auch im Java Development Kit (JDK) lassen sich leicht Beispiele finden. Das Wort »Zip« wird im selben Package mal mit CamelCase und mal komplett in Großbuchstaben geschrieben:

java.util.zip.GZIPInputStream

java.util.zip.ZipOutputStream

Das Setzen des Textes eines Widgets ist nicht einheitlich im JDK gelöst. Mehrheitlich heißt die Methode setText, aber leider gibt es Abweichungen:

java.awt.TextField.setText();

java.awt.Label.setText();

javax.swing.AbstractButton.setText();

java.awt.Button.setLabel();

java.awt.Frame.setTitle();

2.2.2Intuitiv verständlich

Die zweite wichtige Eigenschaft einer guten API ist intuitive Verständlichkeit. Eine intuitiv verständliche API ist in der Regel auch konsistent und verwendet einheitliche Namenskonventionen. Das bedeutet, dass gleiche Dinge die gleichen Namen haben. Und umgekehrt haben unterschiedliche Dinge auch unterschiedliche Namen. Dadurch ergibt sich eine gewisse Vorhersagbarkeit. Betrachten wir dazu ein weiteres Beispiel:

Ruby-Methoden mit Ausrufezeichen (!)

Ruby-Methoden, die mit einem Ausrufezeichen (!) enden, ändern das Objekt, auf dem sie aufgerufen wurden. Methoden ohne Ausrufezeichen am Namensende erzeugen hingegen eine neue Instanz und lassen das Objekt, auf dem sie aufgerufen wurden, unverändert.

my_string.capitalize

# Funktioniert wie capitalize, erzeugt aber keinen neuen String

my_string.capitalize!

my_string.reverse

# Funktioniert wie reverse, erzeugt aber keinen neuen String

my_string.reverse!

Nachdem Sie die Beispiele für capitalize! und reverse! gesehen haben, können Sie vermutlich das Namenspaar für »downcase« erraten.

Setter- und With-Mehoden

Für Java gibt es ebenfalls derartige Konventionen. Eine Konvention betrifft Setter-Methoden wie setName, setId oder setProperty. Setter-Methoden ändern das aufgerufene Objekt. Methoden wie with-Name, withId oder withProperty ändern das aufgerufene Objekt nicht, sondern erzeugen ein neues Objekt mit den angegebenen Werten. Das Präfix »with« wird beispielsweise von Joda-Time genutzt.

Methoden der Java-Collections

Ein anderes anschauliches Beispiel sind die Collections der Java-Standardbibliothek. Die starken Begriffe add, contains und remove wurden hier etabliert und da, wo es passt, wiederverwendet. Man findet diese Methoden einheitlich in den Interfaces List und Set. Für Map wurde leider ein anderer Name verwendet. Die Methode zum Hinzufügen von Elementen heißt dort put. Zugegeben, diese Methode hat andere Parameter und funktioniert nicht wie add von List, aber auch zwischen List und Set gibt es Unterschiede. Ein einheitliches add in allen drei Interfaces wäre vermutlich besser gewesen.

Die folgende Tabelle zeigt die Interfaces von List, Set und Map im Vergleich:

java.util.List

java.util.Set

java.util.Map

add

add

put

addAll

addAll

putAll

contains

contains

containsKey, containsValue

containsAll

containsAll

remove

remove

remove

removeAll

removeAll

Die Tabelle zeigt eine gewisse Symmetrie. Denn es gibt Methodenpaare wie add und remove, addAll und removeAll etc. Die Methode remove-All scheint bei Map zu fehlen, denn diese Methode wäre das Gegenstück zu putAll. Map bietet außerdem die Methode entrySet und keySet, aber nicht die Methode valueSet. Diese Methode heißt korrekterweise values, weil die Mengeneigenschaften in diesem Fall nicht erfüllt werden kann.

Es ist wichtig, starke Begriffe in einer API zu etablieren und diese einheitlich wiederzuverwenden. Beispielsweise sollten Sie nicht Synonyme wie »delete« und »remove« innerhalb einer API beliebig mischen. Entscheiden Sie sich für einen Begriff und bleiben Sie dann dabei. Verwenden Sie Begriffe, die den Benutzern der API geläufig sind. Das Wort »erase« wäre zum Beispiel zu ungewöhnlich. Ein Java-Entwickler würde vermutlich für Dateioperationen nach »create« und »delete« als Erstes suchen. Bei Persistenzoperationen hingegen nach »insert« und »remove«.

Eine API ist intuitiv verständlich, wenn Entwickler den Clientcode der API ohne die Dokumentation lesen können. Das kann nur durch Vorwissen und sprechende Bezeichner funktionieren. Daher sollten Sie gezielt versuchen, Begriffe aus bekannten APIs wiederzuverwenden.

2.2.3Dokumentiert

Eine API sollte möglichst einfach zu benutzen sein. Gute Dokumentation ist für dieses Ziel unverzichtbar. Neben Erklärungen für einzelne Klassen, Methoden und Parameter sollten auch Beispiele in der Dokumentation vorhanden sein. Entwickler können durch Beispiele schnell eine API lernen und benutzen. Im Idealfall findet ein Entwickler ein passendes Beispiel, das mit wenigen Änderungen direkt wiederverwendet werden kann. Die Beispiele der Dokumentation zeigen, wie die API korrekt verwendet werden soll.

Gute Dokumentation kann zum Erfolg einer Technologie beitragen. Das Spring Framework hat beispielsweise eine sehr gute Dokumentation mit vielen sinnvollen Beispielen und Erklärungen. Dies war sicherlich ein Grund für die hohe Akzeptanz des Frameworks.

2.2.4Einprägsam und leicht zu lernen

Wie leicht oder schwer es ist, eine API zu lernen, hängt von vielen unterschiedlichen Faktoren ab. Eine konsistente, intuitiv verständliche und dokumentierte API ist sicherlich einfacher zu lernen als eine inkonsistente, unverständliche und undokumentierte. Die Anzahl der von einer API verwendeten Konzepte, die Wahl der Bezeichner und das individuelle Vorwissen der Benutzer haben ebenfalls großen Einfluss auf die Lernkurve.

APIs sind nur mit Mühe zu erlernen, wenn die Einstiegshürden sehr hoch gelegt werden. Dies ist dann der Fall, wenn viel Code für erste kleine Ergebnisse geschrieben werden muss. Nichts kann einen Benutzer mit Anfängerkenntnissen mehr einschüchtern. Das Webframework Vaadin bietet deswegen auf seiner Website ein Beispiel2 mit geringer Einstiegshürde und »sichtbaren« Ergebnissen:

Das Beispiel zeigt die Verwendung von Widgets – eine Besonderheit für Webframeworks. Dieses Beispiel hat den Vorteil, dass mit nur etwa 10 Zeilen Code ein erstes sichtbares Ergebnis entsteht. Das Beispiel kann man für weitere Experimente nutzen, um das Framework auszuprobieren.

2.2.5Lesbaren Code fördernd

APIs haben enormen Einfluss auf die Lesbarkeit des Clientcodes. Schauen wir uns dazu folgendes Beispiel an:

assertTrue(car.getExtras().contains(airconditioning));

assertEquals(2, car.getExtras().size());

Das Beispiel ist ein Auszug aus einem Unit Test. Die beiden Assertions prüfen, ob das Fahrzeug car eine Klimaanlage und insgesamt zwei Extras hat. Alternativ könnte der Unit Test auch mit dem FEST-Assert-Framework geschrieben werden:

assertThat(car.getExtras())

.hasSize(2)

.contains(airconditioning);

Dank des Fluent Interface, dessen Methodenketten zur Validierung des Testergebnisses stärker an eine natürliche Sprache angelehnt sind, ist der Code des zweiten Beispiels etwas verständlicher. Ein Fluent Interface ist eine Domain Specific Language (DSL), die durch die Anpassung an die Anforderungen ihrer Domäne viel ausdrucksstärker als eine universelle Programmiersprache ist. In Abschnitt 6.1 finden Sie weitere Informationen zu diesem Thema.

Bessere Lesbarkeit und Wartbarkeit von Unit Tests waren die Entwurfsziele des FEST-Assert-Frameworks. In diesem Zusammenhang könnte man noch viele andere Bibliotheken mit gleichem Zweck nennen: Das Spock Famework beispielsweise bietet eine kleine DSL zur übersichtlichen Strukturierung von Tests.

Ein Beispiel aus einem ganz anderen Aufgabengebiet ist die JPA Criteria API. Diese API dient zur Konstruktion von typsicheren Datenbankabfragen. Mit dem folgenden Java-Code wird eine Query gebaut und ausgeführt, um alle Order-Objekte mit mehr als einer Position zu selektieren:

Übersichtlicher wird die Abfrage mit QueryDSL. Diese Bibliothek bietet ein Fluent Interface, mit dem verständliche Pfadausdrücke formuliert werden können.

Entwickler verbringen mehr Zeit mit dem Lesen als mit dem Schreiben von Quellcode. Daher kann deren Produktivität durch gut lesbaren Quellcode bzw. einer leicht verständlichen API verbessert werden. Wie können APIs zu lesbarem Code führen?

Gute Namenskonventionen sind wichtig, denn sie unterstützen das Lesen und Erfassen des Quellcodes. Gut lesbarer Code enthält auch weniger Fehler, denn Fehler fallen dann schneller auf.

Die zuvor beschriebenen Eigenschaften Konsistenz und intuitive Verständlichkeit haben ebenfalls einen großen Einfluss auf die Lesbarkeit des Clientcodes.

Auch ein einheitliches Abstraktionsniveau verbessert die Lesbarkeit von Code. Das bedeutet, dass eine API beispielsweise nicht Persistenzfunktionen mit Geschäftslogik mischen sollte. Das sind Aufgaben unterschiedlicher Abstraktionsniveaus. Wenn diese vermischt werden, entsteht unnötig komplexer Clientcode. Die gewählten Abstraktionen der API sollten passend für die zukünftigen Benutzer ausgewählt werden.

APIs sollten Hilfsmethoden bieten, sodass der Clientcode kurz und verständlich bleibt. Ein Client sollte nichts tun müssen, was ihm die API abnehmen kann.

2.2.6Schwer falsch zu benutzen

Eine API sollte nicht nur einfach zu benutzen, sie sollte sogar schwer falsch zu benutzen sein. Daher sollte man nicht offensichtliche Seiteneffekte vermeiden und Fehler zeitnah mit hilfreichen Fehlermeldungen anzeigen. Benutzer sollten nicht gezwungen sein, die Methoden einer API in einer fest definierten Reihenfolge aufzurufen.

Unerwartetes Verhalten

Die ursprüngliche Datums- und Zeit-API von Java sieht auf den ersten Blick einfach und intuitiv aus. Doch schon bei einfachen Beispielen stolpert man über ein Verhalten, das man vermutlich nicht erwartet. Was das bedeutet, wollen wir uns an einem Beispiel anschauen:

Die ursprüngliche Datums- und Zeit-API von Java lädt geradezu dazu ein, Fehler zu machen. Den 20. Januar 1983 würde man vermutlich so definieren wollen:

Leider enthält diese Codezeile gleich zwei Fehler. Denn die Zeitrechnung dieser API beginnt unerwarteterweise im Jahre 1900. Außerdem sind die Monate beginnend mit 0 durchnummeriert. Die Tage werden beginnend mit 1 angegeben. Deswegen muss der 20. Januar 1983 folgendermaßen erzeugt werden:

Im nächsten Schritt geben wir zusätzlich noch die Uhrzeit 10:17 mit der Zeitzone von Bukarest an. Die Uhrzeit soll schließlich in einen formatierten String umgewandelt werden. Weil die Klasse Date keine Zeitzonen unterstützt, müssen wir ein Calendar-Objekt erzeugen. Die erwartete Ausgabe ist »20.01.1983 10:17 +0200«.

Auch hier verstecken sich mehrere Fehler: Der Konstruktor der Klasse GregorianCalendar akzeptiert eine Zeitzone, aber kein Date-Objekt. Der Calendar kann nicht von SimpleDateFormat formatiert werden. Auch SimpleDateFormat muss die Zeitzone übergeben werden. Durch Angabe der Zeitzone wird die Uhrzeit verändert. Der korrigierte Clientcode sieht so aus:

Aufgrund dieser Fallstricke entstand in der Java-Community die Bibliothek Joda-Time. Der Clientcode könnte folgendermaßen aussehen:

Ein anderes nicht unbedingt intuitives Feature ist die Möglichkeit, mehr als 60 Sekunden, mehr als 24 Stunden usw. bei der Erzeugung eines Date-Objektes anzugeben. Statt einer Fehlermeldung wird der Überhang korrekt berechnet. Durch eine Angabe von beispielsweise 25 Stunden wird der nächste Tag 1 Uhr ausgewählt. Dieses Verhalten ist nicht offensichtlich und könnte deswegen zu Fehlern führen.

2.2.7Minimal

Im Zweifel weglassen!

Eine API sollte prinzipiell so klein wie möglich sein, weil einmal hinzugefügte Elemente nachträglich nicht mehr entfernt werden können. Außerdem sind größere APIs auch komplexer. Dies hat Auswirkungen auf Verständlichkeit und Wartbarkeit der API. Ein ganz anderer Punkt ist der Implementierungsaufwand: Je größer die API, desto aufwendiger ihre Implementierung. Deswegen sollten beispielsweise zusätzliche Hilfsmethoden nur mit Bedacht hinzugefügt werden. Andererseits können Hilfsmethoden sehr nützlich sein. Überhaupt sollte ein Client nichts tun müssen, was eine API übernehmen kann.

Daher braucht man einen Kompromiss, wie ihn die Entwickler der Java-Collection-API gefunden haben: Mit den Methoden addAll und removeAll im Interface java.util.List können mit einem Aufruf mehrere Objekte zu einer Liste hinzugefügt bzw. entfernt werden. Diese Methoden sind optional, weil man Objekte auch einzeln mit add und remove hinzufügen bzw. entfernen kann. Trotzdem ist das Vorhandensein dieser Hilfsmethoden im Interface java.util.List nachvollziehbar und akzeptabel. Diese Hilfsmethoden werden sehr häufig verwendet und passen gut zum Rest des Interface. Andere Hilfsmethoden wie beispielsweise removeAllEven oder removeAllOdd, die alle Objekte mit gerader bzw. ungerader Positionsnummer aus einer Liste entfernen, wären für nur wenige spezielle Anwendungsfälle hilfreich und gehören deswegen nicht in die API.

Die Ruby-Standardbibliothek hat diverse Methoden mehrfach, weil man so im Clientcode besser ausdrücken kann, was man tut. Die Anzahl der Elemente eines Arrays kann z. B. mit length, count und size abgefragt werden. Das muss man nicht ermöglichen, aber es ist ein guter Stil, wenn man ihn konsistent anwendet.

Weniger ist manchmal mehr

Schweizer Messer sind bekannt für ihre zahlreichen Werkzeuge. Neben einer Klinge bieten sie z. B. eine Holzsäge, einen Korkenzieher, eine Schere, eine Metallfeile oder eine Pinzette. Manche dieser Werkzeuge werden kaum oder vielleicht nie benutzt. Ein gewöhnlicher Schraubenzieher mit einem vergleichsweise einfachen Design ist ebenfalls vielseitig einsetzbar: Man kann beispielsweise eine Farbdose mit ihm öffnen, falls der Deckel klemmt. Man kann mit ihm die Farbe umrühren, ein Loch in etwas machen, etwas hinter dem Schrank hervorholen, das man mit der Hand nicht erreichen kann, und man kann sogar Schrauben festdrehen.

Auch eine kleine einfache API kann vielseitig einsetzbar sein. Es muss nicht für jeden Sonderfall eine spezielle Funktion, die am Ende kaum jemand nutzen wird, eingebaut werden. Nichtsdestotrotz sind Schweizer Messer sehr nützlich.

2.2.8Stabil

Stabilität ist eine wichtige Eigenschaft von APIs. Angenommen Sie entwickeln einen Tarifrechner. Ihr Produkt wird ein großer Erfolg und soll in mehrere Kundensysteme integriert werden. Die Integrationen werden von unterschiedlichen Teams durchgeführt und sind relativ teuer, weil Altsysteme nur mit großem Aufwand angepasst werden können. Dann gibt es eine neue Anforderung aus der Fachabteilung und die komplexen Berechnungsregeln des Tarifrechners müssen erweitert werden. Falls sich nun die Schnittstelle oder das bisherige Verhalten dieser Schnittstelle ändern würde, gäbe es Probleme bei der Integration in die Altsysteme. Deswegen muss bei jeder Änderung geprüft werden, ob diese negative Auswirkungen auf bestehende Benutzer hat und wie diese gegebenenfalls kommuniziert werden können. In Kapitel 7 werden wir uns anschauen, welche Änderungen kompatibel sind. Falls Änderungen nicht kompatibel sind, ist gegebenenfalls eine neue Version zu nutzen. Stabilität ist auch bei Einführung einer neuen Version wichtig, wenn Sie die Migration für existierende Clients möglichst einfach machen wollen.

2.2.9Einfach erweiterbar

Eine weitere Eigenschaft von APIs ist Änderbarkeit, ein zentrales Qualitätsmerkmal für Softwareprodukte. Man versteht darunter den erforderlichen Aufwand zur Durchführung vorgegebener Änderungen für Korrekturen, Verbesserungen oder Anpassungen an neue Anforderungen. Diese Eigenschaft ist kein Widerspruch zur zuvor genannten Stabilität, denn gemeint ist Folgendes:

Bei der Erweiterung einer API sollte der Änderungsaufwand für existierende Clients berücksichtigt werden. Im nächsten Abschnitt wird aus diesem Grund die Metrik Konnaszenz vorgestellt.

Im Idealfall ist die veränderte API kompatibel und der Clientcode muss überhaupt nicht angepasst werden.

Eine Java-API kann beispielsweise durch Vererbung erweitert werden:

API-Benutzer können durch Vererbung das Verhalten eines Frameworks anpassen oder ändern.

API-Entwickler können eine neue Subklasse hinzufügen, um auf kompatible Art und Weise neue Funktionen umzusetzen. Die neue Subklasse wird womöglich in einer Factory-Methode erzeugt, sodass API-Benutzer dies nicht bemerken.

Auch für Web-APIs ist Änderbarkeit ein wichtiges Qualitätsmerkmal. Flexible Datenformate wie XML und JSON können genutzt werden, um kompatible Erweiterungen umzusetzen.

2.3Konnaszenz

Für leicht änderbaren Code ist noch keine Zauberformel erfunden worden, aber mit Konnaszenz (engl. Connascence) steht ein gutes Modell zur Verfügung, mit dem wir zumindest über die Änderbarkeit von APIs sprechen können.

Was ist Konnaszenz?

Konnaszenz berücksichtigt verschiedene Typen von Kopplung sowie deren Häufigkeit und Lokalität für Aussagen über die Änderbarkeit von Code (The connascence.io website, 2018). Zwei Komponenten A und B gelten im Sinne von Konnaszenz als gekoppelt, falls eine Änderung an A eine Änderung an B erfordert, um die Korrektheit des Gesamtsystems zu gewährleisten. Eine starke Form von Konnaszenz zwischen A und B ist nur akzeptabel, wenn beide Komponenten eng beieinander liegen, weil sie zum Beispiel Teil derselben Codebasis sind. Umgekehrt ist eine starke Form von Konnaszenz zwischen Komponenten unterschiedlicher Systeme inakzeptabel. Es gilt: Je stärker die Konnaszenz zwischen A und B, desto schwieriger und aufwendiger sind deren Änderungen. Konnaszenz wird mit den Dimensionen Stärke, Häufigkeit und Lokalität beschrieben. Dies kann beim API-Design genutzt werden, um die Verbindung zwischen API und Client zu analysieren:

Stärke

Stärkere Formen von Konnaszenz sind schwerer zu finden oder zu ändern als leichtere Formen. Beispielsweise sind Namensänderungen leicht zu entdecken und durchzuführen. Im Vergleich dazu ist die Anpassung eines Algorithmus, der zwischen API und Client abgestimmt werden muss, schwierig.

Häufigkeit

Die Änderung einer API, die sehr viele Clients hat, ist höchstwahrscheinlich eine größere Herausforderung als die Änderung einer API mit wenigen Clients. Die Änderbarkeit von öffentlichen APIs mit vielen Clients ist daher stark eingeschränkt.

Lokalität

Je weiter API und Client entfernt sind, desto schwieriger sind Änderungen. Wenn API und Client zur selben Codebasis gehören, ist die Änderung vergleichsweise einfach. Änderungen innerhalb des Zuständigkeitsbereichs eines Entwicklungsteams sind ebenfalls akzeptabel. Aber Änderungen über Organisationsgrenzen hinweg sind deutlich komplexer, weil die Organisationen wahrscheinlich verschiedene Ziele verfolgen, unterschiedliche Releasezyklen haben und die Kommunikation insgesamt schwieriger oder aufwendiger ist als innerhalb eines Teams.

Statische Konnaszenz