Thomas Ronzon (TR): Hallo ihr beiden. Heute wollen wir uns mal mit Design Patterns für APIs beschäftigen. Könnt ihr kurz erklären, was man unter Patterns versteht?
Olaf Zimmermann: Gerne. Ein Design Pattern (deutsch Entwurfsmuster) zeigt die Lösung eines Problems in einem Kontext. Eine wichtige Rolle spielen die sogenannten Forces. Das sind Sachen, die das Problem schwierig und interessant machen, bildlich also Kräfte, die auf das Design einwirken. Ein Beispiel ist der Wunsch nach kurzen Antwortzeiten. Positive und negative Konsequenzen der Anwendung des Musters im Hinblick auf solche Kräfte werden diskutiert. Dazu kommen dann noch die "Known Uses", also Vorkommen des Musters in der Praxis, sowie Implementierungsskizzen.
Daniel Lübke: Nehmen wir Pagination ([MAP], s. Abb. 1) als Beispiel.
Abb. 1: Muster Pagination [MAP]
Das Pattern kennen vermutlich die meisten, und sein Name hat sich etabliert. Namen sind bei Mustern wichtig. Es entsteht eine (Fach-)Sprache, die mit einfachen Wörtern komplexe Lösungsideen beschreibt. Wer kennt nicht den Iterator, Listener oder die Factory? Bei Pagination unterteilen wir eine große Antwort in Pages (deutsch Seiten). Damit lösen wir das Problem der zu großen Antwortnachrichten. Haben wir dieses Problem nicht in unserem Anwendungs- oder Projektkontext, ist die Nutzung von Pagination nicht sinnvoll. Pagination hat aber auch Nachteile: Statt einer Antwort erhält der API-Client mehrere, und mehr Logik auf der Client- und der Provider-Seite ist erforderlich, um Anfragen zu beantworten und die Antworten abzuarbeiten. Diese Aspekte sind Forces und im Pattern entsprechend beschrieben. Einige Qualitätseigenschaften werden bei Einsatz des Musters besser, andere schlechter.
TR: Muss man nun immer Pagination verwenden, wenn man zu große Antwort-Nachrichten hat?
Olaf: Nein, es gibt auch andere Möglichkeiten, wie Daten nur per Referenz zu übertragen (Linked Information Holder-Pattern, [LHP]) oder nur eine durch den Client definierte Anzahl an Attributen in die Antwort aufzunehmen (Wish List [WL] und Wish Template [WT]).
TR: Das ging jetzt aber sehr schnell sehr tief. Kehren wir noch mal zum Begriff API und eurem Fokus zurück, bitte.
Olaf: Ok. API definieren wir im Buch als „Access to Services via Integration”. Wir fokussieren dabei nicht auf lokale APIs innerhalb eines Anwendungsprogramms oder zwischen Programm und Betriebssystem, sondern auf nachrichtenbasierte APIs zwischen verschiedenen Programmen und Prozessen, die gern auch auf mehrere Host-Rechner auf der ganzen Welt und in den Wolken verteilt sein dürfen. Web APIs, die mehr oder weniger RESTvoll JSON-Objekte über HTTP versenden, sind wichtige Vertreter dieser Art. Es gibt aber auch gRPC, GraphQL und asynchrone Messaging-Kanäle [VERG]. Diese Arten von Remote APIs haben gemeinsam, dass sie Dokumente austauschen, in denen über Ereignisse berichtet wird, oder dass Kommandos samt Parametern enthalten sind. Viele Designprobleme treten unabhängig von der Protokollwahl immer wieder auf, was die Beschreibung bewährter Lösungen als Patterns besonders interessant macht.
Daniel: Gerade der letzte Punkt ist aus praktischer Sicht interessant. Keiner redet heute mehr über CORBA, auch wenn es damals ein Hype war. Aber die Ideen bezüglich der Serviceorientierung, die wir heute noch verwenden, entstammen dieser Zeit. Viele Patterns wie Remote Proxy haben sich schon damals ausgeprägt und sind dann auch in Web-Services-Projekten adaptiert worden. Heute werde sie dann wiederum mit moderneren Integrationstechnologien umgesetzt. API Gateways mit ihren Transformations- und Routingfeatures sind ein gutes Beispiel für eine aktuelle Umsetzung des Musters Message Broker.
TR: Aha, wir wollen also eine Runde Buzzword-Bingo spielen?
Olaf: Gern! APIs sind technische Enabler für alle großen IT-Trends von Cloud-Computing über Microservices, IoT und Big Data hin zu Blockchain und KI/ML. Bingo! So verschieden alle diese Themen und deren unterliegende Technologien sein mögen: Reden müssen die Anwendungsteile miteinander, und es gilt zu entwerfen, wer wann wie viel mit wem redet (und warum). Datensparsamkeit, Änderungsfreundlichkeit und Developer Experience spielen in den meisten, wenn nicht allen diesen Domänen eine kräftige Rolle. Auch die aktuell gehypten KIs benötigen Daten. Und woher kommen die? Natürlich über APIs!
Daniel: Damit wären wir wieder bei den Patterns als geeignetes Know-how-Austauschmedium. Ein gut gemachtes Pattern ist dabei kein exakter Blueprint (dt. Bauplan) und keine fertig implementierte Library, sondern lässt den API-Designern Gestaltungsspielraum; Copy-Paste ist weder möglich noch gewollt. Oder anders formuliert: Ein Pattern beschreibt die Essenz einer konzeptionellen Antwort auf eine relevante, spannende Designfrage, die sich mindestens dreimal bewährt hat (was man mit den Known Uses demonstriert).
TR: Nun habt ihr ja mit über 500 Seiten ein ziemlich dickes Buch hierzu herausgebracht. Wie seid ihr auf die Idee gekommen und wer ist die Zielgruppe?
Daniel: Geplant waren 200 Seiten. Nach Schlussredaktion und im Production-Layout waren es dann auf einmal etwas mehr. Das Buch ist sicher eher ein Literatur-Vollkornbrot denn ein Bagel oder Donut. Es hat aber sowohl einführenden als auch Refererenzcharakter. Man muss nicht Cover-to-Cover lesen – Teil 2 des Buchs beispielsweise ist als Nachschlagewerk und Checkliste für die tägliche API-Design-Arbeit angelegt. Wenn ein bestimmtes Designproblem auftritt oder eine Qualitätseigenschaft einfach nicht erreichbar zu sein scheint, kann man nachschauen, ob bestimmte Patterns anwendbar sind. Es geht dabei nie darum, möglichst viele Patterns zu benutzen, sondern die relevanten für seinen eigenen Projektkontext zu finden. Generell lese ich daher Pattern-Bücher gerne quer, um zu wissen, was es für Patterns gibt, um dann im Projektalltag reagieren zu können: "Hey, da gab es etwas, ich sollte nachschauen."
Olaf: Patterns zu schreiben, war lange auf unserer "Bucket List". Evelyn Hamann würde sagen: Als beratende Architekten „etwas Eigenes haben“ [JD]. Wir sind Fans und Anwender der ersten Stunde: Es ging ca. 1995 los mit dem Buch der Gang of Four [GoF], dann kamen einige Bücher von Martin Fowler (z. B. "Analysis Patterns" [Fow96], "Patterns of Enterprise Application Architecture" [Fow02]); die "Enterprise Integration Patterns" von Bobby Woolf und Gregor Hohpe [Ho-Wo03], die dieses Jahr 20 werden, sind ein weiterer Favorit. Es braucht Praxis-Erfahrung im Thema, Zeit und Hingabe sowie etwas Schreibtalent, um sich an diese Aufgabe heranzuwagen; die Kombination der drei Faktoren ist nicht einfach hinzubekommen. Wir hatten lange Respekt vor der Herausforderung – und haben in der Zwischenzeit mit Architekturentscheidungs- und Prozessmodellen geübt [AE, AP].
Daniel: Die Konferenz EuroPLoP half uns, das Handwerk (oder die Kunst?) des Patternschreibens zu erlernen mit einem Introductory Information Pack [EP] und "Writers Workshops", einem tollen Format. Man liest Intermediate Drafts voneinander und muss als "Fly on the Wall", wenn die anderen Teilnehmenden die eigenen Ideen und Texte freundlich kommentieren, zuhören (was erschwerenderweise auch heißt, nicht zu reden). Es gibt zuvor auch ein Coaching-Angebot, Shepherding genannt. Hier stimmt unserer Meinung nach die Metapher nicht ganz (welche Schafe werden später Hirten?), und es hängt stark an Motivation und Einsatz von Hirten und Schafen, wie nützlich es ist.
TR: Wie unterscheidet sich euer Buch von anderen in dem Gebiet?
Olaf: "Patterns for API Design" [Zim22] ist ein Dritte-Generation-Buch nach einer Welle von Technikbüchern (z. B. zu RESTful HTTP) und einer weiteren Welle mit Zielen, Prozessen und Prinzipien wie API First (oft falsch verstanden, aber wichtig) [AFI]. Es generalisiert und verdichtet Konzepte aus den Büchern der ersten beiden Generationen und vielen weiteren Quellen aus Praxis und Forschung.
TR: Und warum sollte ich dann euer Buch lesen?
Daniel: Wir sind unserer Kenntnis nach die Einzigen, die in die Antwort-Nachrichten (s. o.) reinschauen. Ein Bild kann das veranschaulichen: Wie man telefoniert und chattet und emailt, ist technisch verstanden, da gibt es sogar Standards und interoperable Protokolle (GSM, 4G, POP, IMAP usw.). Aber was man sagt im Gespräch oder wie groß man seine Chat-Nachricht macht und wie viel Traffic das bringt, muss jede(r) Gesprächsteilnehmende für jede Nachricht neu entscheiden. Das ist im API-Design auch so. Wir zeigen auf, was Programme für Möglichkeiten haben, einander zu aktivieren und Daten auszutauschen, welche API-Granularität welche Auswirkungen auf die Developer Experience und die Laufzeiten hat, wie man Identitäts- und Zustandsmanagement hinbekommt und vieles mehr.
Olaf: Wenn du eine Kostprobe haben möchtest: Die Webseite und Videos laden zum Reinschnuppern ein, und es gibt auch Sample Content vom Verlag (u. a. Kapitel 7) und bei einem namhaften Online-Buchhändler (u. a. Kapitel 1) [BUCH].
TR: Und wie seid ihr an all diese Informationen gekommen – ich meine, so was denkt man sich doch nicht einfach aus, oder?
Olaf: Richtig, "Patterns for API Design" schürft man aus Known Uses, man erfindet sie nicht. Ich habe über 100 Web-APIs in meinem Sabbatical 2016 angesehen, ein Google Doc mit Kandidaten aus der Enterprise-Welt war dann unsere erste gemeinsame Aktion. Unser Co-Autor Mirko Stocker, er ist agiler Full Stack Developer mit Schwerpunkt auf Cloud Native Applications, sollte erst nur Korrektur lesen und Beispiele programmieren, brachte aber von Anfang an viele sehr gute Fragen und gleich noch Antworten aus seinen Projekten ein und wurde dann unser API-Qualitätsspezialist – und kümmert sich auch um API Refactorings [IRC]. Zwei erfahrene Pattern-Schreiber kamen schließlich auch noch dazu, mit Forschungsschwerpunkten auf Web Development und REST beziehungsweise Architekturentscheidungen, DevOps und Modellierung (schon wieder Bingo!).
Daniel: Meine Motivation war, dass ich in vielen Projekten Service-Designern (so hießen die API-Designer vor noch gar nicht allzu langer Zeit) immer dieselben Sachen erklären musste. Für solche Situationen sind Patterns eine tolle Sache, weil man auf sie verweisen kann (die Pattern-Namen sind wichtig!) und die Patterns über die Forces/Kräfte bereits die Argumentation klar vorgeben.
Olaf: Zurück zum Content Development. Wir waren viermal von 2017 bis 2023 auf der EuroPLoP-Konferenz mit jeweils einer Kategorie von Patterns. Dadurch hatten wir zahlreiche Testleser. Ebenso bauten wir die Webseite www.api-patterns.org [MAP] auf. Den Series Editor Vaughn Vernon lernte ich über das Open-Source-Projekt "Context Mappe" [CM] kennen. Und dann fing die eigentliche Arbeit an: UML-Diagramme, Known Uses, Beispiele, Templatekonformität, Korrektheit, Balance zwischen zeitlos und aktuell relevant usw. Ein Buch macht erheblich mehr Arbeit, als man denkt, aber mit dem Endprodukt sind wir doch sehr zufrieden.
TR: Ein meiner Meinung nach wichtiges und vielfach unterschätztes Thema ist die Versionierung von Schnittstellen. Was meint ihr? Habt ihr hier ein paar Ansätze?
Daniel: Theorie und Praxis divergieren hier stark. Die oftmals postulierte volle Abwärtskompatibilität ist Wunschdenken, denn die Welt ändert sich. Von der Einführung des Euros und der IBAN, über neue Sicherheitsprotokolle bis hin zur DSGVO: Wenn die Welt sich (regulatorisch) ändert, dann müssen Softwaresysteme und somit APIs nachziehen. Aber auch so verstehen wir die Anforderungen von Clients besser, müssen neue Funktionen bauen und stehen vor der Aufgabe, unsere APIs zu refaktorieren, was nicht immer abwärtskompatibel ist. Daher sind Lifecycle Management und Extensibility als nachhaltige Qualitätseigenschaften wichtig, bringen aber leider immer auch eine Wette auf die Zukunft mit sich. Insofern müssen APIs eine klare Evolutionsstrategie haben. Es muss für Clients klar sein, welche Anforderungen zu Änderungen führen, die nicht kompatibel sind.
TR: Okay – habt ihr hier vielleicht ein paar Tipps für die Praxis?
Olaf und Daniel: Lass uns doch einen Blick auf unsere Pattern Map im Kapitel "Evolve APIs" werfen (s. Abb. 2).
Abb. 2: Pattern Map im Kapitel „Evolve APIs“ von [MAP]
Im Kern ist die Frage, wie viele Garantien gebe ich als Serviceanbieter meinen Aufrufern. Möchte ich nur etwas testen (so wie Google Betas), dann gibt es den "Experimental Preview", der im Wesentlichen sagt, dass man die API auf eigene Gefahr nutzen kann. Es gibt keine Garantien bzgl. Kompatibilität. Möchte man die Lebenszyklen zwischen Service-Anbieter und -Nutzer besser abstimmen, so muss es eine andere Strategie geben. Klassisch ist "Two in Production", wo alte Versionen noch eine Zeit lang angeboten werden; allerdings nur max. 2 (manchmal auch 3) gleichzeitig. Alte Versionen werden also mit neueren abgekündigt. "Limited Lifetime Guarantee" ist ähnlich, nur dass hier der Auslöser eine vorher angekündigte Zeit ist, wie lange man eine API-Version unterstützt. Dagegen gibt es mit "Aggressive Obsolescence" eine Variante, bei der man Features deprecated und dann nach einer gegebenen Warnfrist nicht mehr unterstützt. Egal, was es dann für eine Variante wird: Man sollte es klar an die Aufrufer kommunizieren, damit diese planen können!
TR: Was habt ihr für Feedback für euer Buch bekommen?
Olaf: Als Vollkornbrot unter den API-Büchern ist unser Buch gehaltvoll und sättigend; man braucht aber Zeit zum Kauen und Verdauen. Die, die sich schon durchgegessen haben, mögen beispielsweise die Architectural Decision Records (ADRs) und die zahlreichen Beispiele. Der Signature Series Editor Vaughn Vernon, Autor von "Implementing DDD" [DDD], war sogar euphorisch in seinen LinkedIn Announcements – nicht nur, aber auch wegen der Sprachstruktur und unserer kompakten Schnittstellen- und Service-Beschreibungs-DSL. Diese entwarfen wir in einem Forschungsprojekt, denn ein halbwegs realistisches API-Beispiel passte vorher nicht auf eine Buchseite oder Powerpoint-Folie!
Abb. 3: Gotische Architektur, dieses Werk wurde von seinem Urheber Hill als gemeinfrei veröffentlicht.
Daniel: Nach der Veröffentlichung des Buchs wurden wir auch für einige Podcasts angefragt (z. B. Tech Lead Journal [TLJ]). Auf dem YouTube-API-Kanal von Erik Wilde findet sich ein Video über unsere Patternsprache [WIL]. All dies stieß auf sehr reges Interesse. Zudem haben wir die Patterns auf Konferenzen wie der JAX und einer API-Konferenz in London vorgestellt, wo es zu interessanten Diskussionen kam und wir viel positives Feedback bekommen haben. Auch auf LinkedIn gibt es immer wieder freundliche Reaktionen zu unseren Beiträgen rund um das Thema. Ein niederländischer API-Architekt hat sogar eine User Group um die Patterns formiert!
TR: Ein Teil, der mir fehlte, ist ein Leitfaden zur praktischen Umsetzung. Sei es zu dem Vorgehen, sei es zu der technischen Umsetzung. Ich stelle zum Beispiel immer wieder fest, dass es vielen nicht bewusst ist, dass Datentypen in unterschiedlichen Sprachen beziehungsweise Techniken unterschiedlich definiert sind. Mein Lieblingsbeispiel ist, dass Integer-Zahlen, also int in ANSI-C als "prozessbusbreite Datentypen" definiert sind. Habt ihr hier auch Tipps?
Olaf und Daniel: Im Buch gibt es in Kapitel 3 Entscheidungsmodelle zu allen Patterns. Diese zeigen zwar nur einen Teil des gesamten API-Design-Prozesses, aber eben genau den Teil, den wir mit unseren Patterns abdecken. Zum schnelleren Überblick gibt es auch ein Pattern Cheat Sheet im Anhang.
Zur technischen Umsetzung sagen wir in der Tat – und ganz bewusst – weniger. Dazu gibt es bereits viel Literatur, wie die Bücher von Arnaut Lauret [AFI] und von Subbhu Allamaraju [All10]. Unsere Patterns sind dagegen technologieoffen. Einige Patterns haben wir wie schon besprochen in CORBA-Projekten erlebt (Okay, das ist schon recht lange her). Der Erfinder des Pattern-Konzepts, Gebäude-Architekt Christopher Alexander, nennt diesen Anspruch "Timeless Way of Building" [TWOB]. Zur Unterstützung in der Umsetzung sammeln wir Implementation Hints für jedes Pattern, die zum Teil bereits in unseren EuroPLoP-Artikeln [EP1, EP2, EP3, EP4, EP5] enthalten waren. Und unsere Microservices-Beispielanwendung Lakeside Mutual, eine Businessapplikation in einer fiktiven Versicherung, implementiert die meisten Patterns in Java mit Spring Boot [EXA]. Und es gibt ja auch einen schönen Tool-Tipp in JavaSPEKTRUM [JS].
Einen ganz einfachen Vorschlag für die Pattern-Nutzung haben wir dann noch zum Abschluss: Die Pattern Maps im Buch oder der Index auf der Webseite können auch als Checklisten fungieren. Man vergisst gerne im Projektstress irgendwas, und einfach schnell einmal durch diese Listen zu gehen, ist erstaunlich hilfreich dabei, noch einmal bewusst Entscheidungen zu hinterfragen und zu treffen [CHECK].
Das sind Dr. Olaf Zimmermann und Dr.-Ing. Daniel Lübke
Dr. Olaf Zimmermann ist seit 2013 Professor für Softwarearchitektur an der OST – Ostschweizer Fachhochschule. Er entwirft, nutzt und begutachtet Schnittstellen aller Art seit dem Beginn seiner Industrielaufbahn 1994. Besonders wichtig sind ihm dabei gute Begründungen der Architekturentscheidungen.
Dr.-Ing. Daniel Lübke ist geschäftsführender Gesellschafter der Digital Solution Architecture GmbH. Er betreut Kunden in Digitalisierungsprojekten und ist verantwortlich für die Softwarearchitekturen und die Geschäftsprozessautomatisierung. Daniel hält regelmäßig Vorträge auf Konferenzen und ist Autor zahlreicher Fachbeiträge in verschiedenen Zeitschriften.
Weitere Informationen
[AE] Artikel und Präsentationen zu Architekturentscheidungen, via
https://ozimmer.ch
[AFI] A. Lauret, How to enhance your API-first design process, 27.3.2023,
https://blog.postman.com/how-to-enhance-your-api-first-design-process/
[All10] S. Allamaraju, RESTful Web Services Cookbook, O’ Reilly, 2010
[AP] Artikel und Präsentationen zu Geschäftsprozessmodellierung, via
https://www.digital-solution-architecture.com/
[BUCH] O. Zimmermann, D. Lübke, C. Pautasso, M. Stocker, U. Zdun, What is the Right Service Granularity in APIs?, Addison-Wesley Professional, 2020, s.
https://www.informit.com/articles/article.aspx?p=3153211
[CHECK] O. Zimmermann, A Checklist for API Design Review,
https://medium.com/nerd-for-tech/a-checklist-for-api-designreviews-5f7db45b0cb3
[CM] Context Mapper
https://contextmapper.org/
[DDD] V. Vernon, Implementing Domain-Driven Design, Addison-Wesley, 2013
[EP] Hillside Europe, Introductory Information Pack,
https://europlop.net/wp-content/uploads/2022/10/pattern_ introduction_pack.zip
[EP1] O. Zimmermann et al., Interface representation patterns: crafting and consuming message-based remote APIs, in: Proc. of the 22nd European Conference on Pattern Languages of Programs (EuroPLoP), 2017
[EP2] M. Stocker et al., Interface quality patterns: Communicating and Improving the Quality of Microservices APIs, in: Proc. of the 23rd EuroPLoP, 2018
[EP3] D. Lübke et al., Interface evolution patterns: Balancing compatibility and extensibility across service life cycles, in: Proc. of the 24th EuroPLoP, 2019
[EP4] O. Zimmermann et al., Interface responsibility patterns: processing resources and operation responsibilities, in: Proc. of the 25th EuroPLoP, 2020
[EP5] O. Zimmermann et al., Data-oriented interface responsibility patterns: Types of information holder resources, in: Proc. of the 25th EuroPLoP, 2020
[EXA] Lakeside Mutual,
https://github.com/Microservice-API-Patterns/LakesideMutual
[Fow96] M. Fowler, Analysis Patterns: Reusable Object Models, Addison-Wesley Professional, 1996
[Fow02] M. Fowler, Patterns of Enterprise Application Architecture, Addison Wesley, 2002
[GoF] E. Gamma et al., Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley Professional, 1994
[HoWo03] G. Hohpe, B. Woolf, Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions, Addison-Wesley Professional, 2003
[IRC] Interface Refactoring Catalog,
https://interface-refactoring.github.io/
[JD]
https://de.wikipedia.org/wiki/Jodeldiplom
[JS]
https://file.sigs-datacom.de/publications/download/Artikel/ronzon_JS_01_20_lklo.pdf
[LHP]
https://api-patterns.org/patterns/quality/referenceManagement/LinkedInformationHolder
[MAP] Microservice API Patterns,
https://microservice-api-patterns.org/
[PAG] https://api-patterns.org/patterns/quality/dataTransferParsimony/Pagination
[TLJ] D. Luebke, Patterns for API Design, Tech Lead Journal: #125, 20.4.2023,
https://techleadjournal.dev/episodes/125/
[TWOB] C. Alexander, The Timeless Way of Building, Oxford University Press, 1979
[VERG] T. Bayer, REST, GraphQL und gRPC im Vergleich, zuletzt aktualisiert am 2.4.21,
https://www.predic8.de/rest-graphql-grpc-api-vergleich-artikel.htm
[WIL] E. Wilde, Microservice API Patterns: A Language for API Design,
https://www.youtube.com/watch?v=cNp7ys0g0Bs
[WL] https://api-patterns.org/patterns/quality/dataTransferParsimony/WishList
[WT] https://api-patterns.org/patterns/quality/dataTransferParsimony/WishTemplate
[Zim22] O. Zimmermann, M. Stocker, D. Lübke, U. Zdun, C. Pautasso, Patterns for API Design: Simplifying Integration with Loosely Coupled Message Exchanges, Addison-Wesley Signature Series (Hrsg. V. Vernon), 2022
Das Interview führte Thomas Ronzon.