Warum Consumer-Driven statt Provider-Driven APIs?

Wer eine Migration zu einer cloud-nativen Architektur erlebt, stellt schnell fest, dass die Anzahl der Services und damit zwangsläufig die Zahl der Schnittstellen wächst. Per Definition betreffen Änderungen der Schnittstellen mehrere Service-Komponenten, nämlich den Provider der Schnittstelle und ihre Consumer. Und in der Regel werden diese Komponenten von verschiedenen Teams entwickelt. Änderungen an Schnittstellen erzeugen also Aufwände für Abstimmungen und ein erhöhtes Integrationsrisiko.
Oft scheint es naheliegend, dass das Provider-Team die Schnittstellen entwirft. Schließlich sind die Entwickler des Providers auch am besten mit den Anforderungen und den Details der Umsetzung vertraut, oder?
Dass das nicht ganz stimmt wird deutlich, wenn es dem Provider-Team schwerfällt, die Schnittstelle so zu dokumentieren, dass Consumer-Teams sie auch verstehen. Ich erinnere mich schmerzhaft daran, mehrere Seiten an Swagger-Dokumentation mit ausführlichen Erklärungen versehen zu haben, nur um dann doch in mehrstündigen Workshops verwirrten Consumer-Teams zu helfen, die für sie relevanten Teile der Schnittstellen zu verstehen. Wenn eine komplexe Schnittstelle mit schwer verständlicher Dokumentation der erste Anstoß für ein Gespräch ist, dann ist das bereits reichlich spät.
Consumer früh einbeziehen
Der Gegenentwurf zu vom Provider vorgegebenen Schnittstellen-Spezifikationen sind Consumer-Driven Contracts. Ein Consumer-Driven Contract (CDC) besteht (wie der Name schon sagt) aus den Erwartungen aller Consumer einer Schnittstelle an den Provider. Dass Consumer die Schnittstelle mit-spezifizieren wird vom Provider-Team schnell als Kontrollverlust missverstanden. Das Gegenteil ist der Fall.
Zunächst einmal: nur wenn das Provider-Team die Erwartungen eines Consumer-Teams akzeptiert, entsteht eine Vereinbarung, ein Contract. Ein Contract kann also nur zustande kommen, wenn sich beide Teams vorher über die Schnittstelle unterhalten und zugestimmt haben. Entsprechend kommen die Teams früh ins Gespräch und das Provider-Team weiß genau, für welche Consumer es die Schnittstelle umsetzt. Für das Provider-Team ergeben sich dadurch drei Vorteile:
- sie wissen genau, welche Schnittstellenelemente tatsächlich benötigt werden und müssen nicht spekulieren;
- sie wissen, welcher Consumer von einer notwendigen Schnittstellen-Änderung betroffen ist und können gezielt kommunizieren;
- sie wissen, welche Schnittstellenelemente nicht mehr verwendet werden und entfernt werden können.
So lassen sich Gespräche gezielt führen und unnötige Abstimmungen vermeiden. Die Consumer und ihre Erwartungen zu kennen, gibt dem Provider-Team also entschieden mehr Kontrolle über die Entwicklung der Schnittstelle. Besonders das Erkennen nicht verwendeter Elemente einer Schnittstelle, ist die Grundlage für evolutionäre API-Entwicklung.
Consumer-Driven APIs sind simpler
Consumer-Teams stehen vor der Herausforderung, die Erwartungen an eine Schnittstelle formal zu spezifizieren. Manchmal wird das als Schreiben von Tests für den Provider missverstanden. Tatsächlich kann Consumer-Driven Contract Testing als ein testgetriebener Entwurfsansatz, analog zu Test-Driven Development (TDD), verstanden werden.
Entscheidend ist, dass das Consumer-Team nicht den Provider testet, sondern eine gemeinsame Schnittstelle entwirft. Dadurch dass das Consumer-Team den Contract schreibt, gibt er dessen Verständnis wieder. Das hilft nicht nur bei der Kommunikation. Die Schnittstelle ist damit auch konzeptionell näher am Consumer und stellt dessen Sicht auf den Provider dar. Es macht einen Unterschied, ob ich „den Lichtschalter drücke“ oder „den Laststromkreis der Beleuchtungsanlage schließe“.
Der Provider kann gegenüber verschiedenen Consumer unterschiedliche Rollen einnehmen. Wenn wenig Überlappungen in den Erwartungen der Consumer an eine Schnittstelle bestehen, ist es sinnvoll, mehrere Rollen-spezifische Schnittstellen anzulegen. Der Mehraufwand, der durch zusätzliche Schnittstellen entsteht, kann auf lange Sicht wieder eingespart werden, weil Rollen-spezifische Schnittstellen kleiner und stabiler sind und sich Änderungsaufwände auf weniger Consumer beschränken.
Ich bin hier spezifisch auf die Vorteile von Consumer-Driven Contracts für den Schnittstellenentwurf eingegangen. Die Vorteile für Automatisierung und Integrationstests beschreibt meine Kollegin Antoniya.
Aktuelle Beiträge






Artikel kommentieren