Philip Withnall
philip.withnall@collabora.co.uk 2015

This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.

Als besondere Ausnahme gewähren die Inhaber des Urheberrechts die Erlaubnis, den Beispiel-Code in diesem Dokument ohne Einschränkungen unter den Bedingungen Ihrer Wahl zu kopieren, zu verändern und weiterzugeben.

Abwärtskompatibilität in APIs
Mario Blättermann
mario.blaettermann@gmail.com 2016, 2018
Christian Kirbach
christian.kirbach@gmail.com 2016, 2020
Stefan Melmuk
stefan.melmuk@gmail.com 2018
Tim Sabsch
tim@sabsch.com 2021

# API-Stabilität

#

        Zusammenfassung

          Bestimmen Sie API-Stabilitätsgarantien für Ihr Projekt. ()
          Stellen Sie sicher, dass bei API-Änderungen auch die entsprechende Versionsnummer geändert wird. ()

# API und ABI

Auf höherer Ebene ist eine API (Application Programming Interface) die Schnittstelle zwischen zwei Komponenten, die gegeneinander entwickelt werden. Sie ist nah verwandt mit der ABI (Application Binary Interface), der Binärschnittstelle zur Laufzeit. Eine Schnittstelle bestimmt die verschiedenen Möglichkeiten, wie andere Komponenten mit einer Komponente interagieren können. Im Normalfalls stellen die C-Header einer Bibliothek die API und die kompilierten Symbole die ABI einer Bibliothek dar . Der Unterschied zwischen API und ABI kommt vor allem durch die Kompilation des Quelltextes: so befinden sich in einer C-Headerdatei gewisse Sachen wie `#define`-Anweisungen, die zur Änderung der API führen können, ohne dass sich die ABI ändert. In der Praxis können die Unterschiede zwischen API und ABI aber vernachlässigt werden, weil sie meistens austauschbar behandelbar sind.

Beispiele für API-inkompatible Änderungen einer C-Funktion wären das Hinzufügen eines neuen Parameters, Ändern des Rückgabetyps einer Funktion oder die Entfernung eines Parameters.

Aber auch andere Teile eines Projekts können eine API darstellen. Wenn sich ein Daemon über D-Bus exponiert, stellen die dort exportierten Schnittstellen eine API dar. Wenn eine C-API in einer höheren Programmiersprache durch Verwendung von GIR offengelegt wird, dann stellt die GIR-Datei eine andere Form von API dar — wenn sie sich ändert, muss sich auch der gesamte Code ändern, der sich darauf bezieht.

Andere Beispiele von eher ungewöhnlichen APIs sind Konfigurationsdateiorte und -formate und GSettings-Schemas. Änderungenen an diesen könnten es erforderlich machen, dass sich auch Code ändern muss, der eine Bibliothek verwendet.

# Stabilität

API-Stabilität bezieht sich darauf, inwiefern ein Projekt garantiert, dass sich seine API nur auf bestimmten Wege verändern oder auch nicht mehr verändern wird. Allgemein wird eine API dann als sicher betrachtet, wenn sie sich auf Abwärtskompatibilität festlegt; eine API könnte sich aber auch darauf festlegen, instabil oder aufwärtskompatibel zu sein. Der Zweck einer API-Stabilitätsgarantie ist es anderen zu ermöglichen, ein Projekt in ihrem Code zu verwenden, ohne dass sie sich ständig Sorgen machen müssen, ihren Code dauernd ändern zu müssen, um API-Änderungen zu berücksichtigen. Eine typische API-Stabilitätsgarantie wäre, dass Code, der gegen eine bestimmte Version einer Bibliothek kompiliert wurde, ohne Probleme auch mit zukünftigen Versionen dieser Bibliothek mit derselben Hauptversionsnummer laufen wird — oder auch, dass Code, der gegen einen Daemon programmiert wurde, auch auf zukünftigen Versionen mit derselben Hauptversionsnummer laufen wird.

Es ist möglich, verschiedene Ebenen von API-Stabilitätsgarantien auf Komponententen innerhalb eines Projekts anzubringen. Zum Beispiel könnten die Kernfunktionalitäten einer Bibliothek stabil sein und deshalb auch deren API unverändert bleiben, während die neueren, sekundäreren Funktionenen instabil bleiben und sich sehr stark ändern dürfen, solange bis das richtige Design gefunden wurde und sie dann als sicher gekennzeichnet werden könnten.

Im Allgemeinen werden verschiedene Typen der Stabilität bezeichnet:

## Instabil (unstable)

Die API kann sich ändern oder in der Zukunft geändert werden.

## Backwards compatible (Abwärtskompatibilität)

Es sind nur solche Änderungen zulässig, die einem Code, der gegen die unmodifizierte API kompiliert wird, erlauben, auch mit der geänderten API zu laufen (z.B. können keine Funktionen entfernt werden).

## Forwards compatible (Aufwärtskompatibilität)

Es sind nur solche Änderungen zulässig, die einem Code, der gegen die modifizierte API kompiliert wird, erlauben, auch mit der vorherigen API zu laufen (z.B. können keine Funktionen hinzugefügt werden).

## Gänzlich unveränderlich (totally stable)

Es sind keine Änderungen an der API erlaubt, nur an deren Implementation.

Üblicherweise verpflichtet sich ein Projekt zur Abwärtskompatibilität, wenn es meint, eine API wäre 'stabil' (stable). Die wenigsten Projekte verpflichten sich zu einer gänzlichen Unveränderlichkeit (total stability), weil es fast die ganze weitere Entwicklung des Projektes verhindern würde.

# Versionierung

API-Stabilitätsgarantien sind eng mit der Versionierung des Projekts verknüpft; das betrifft sowohl die Paket- als auch die Libtool-Versionierung. Letztere dient ausschließlich dem Zweck, die API-Stabilität zu überwachen, sie wird detailliert in Autotools Mythbuster oder erklärt.

Paketversionierung (major.minor.micro) ist eng mit API-Stabilität verknüpft: typischerweise, wird die Hauptversionsnummer (major version number) erhöht, wenn eine Änderung nicht mehr abwärtskompatibel ist (zum Beispiel wenn Funktionen umbenannt, Parameter geändert oder Funktionen entfernt werden). Die Nebenversionsnummer (minor version number) wird erhöht, wenn eine Änderung nicht mehr aufwärtskompatibel ist (zum Beispiel wenn eine neue öffentliche API hinzugefügt wird). Die dritte Versionsnummer (micro version number) wird erhöht, wenn die Code-Änderungen ohne Änderung der API möglich sind. Siehe für weitere Informationen.

API-Versionierung ist genauso wichtig für D-Bus-Schnittstellen und GSettings-Schemas (falls sie sich häufiger ändern) wie für C-Programmierschnittstellen. Siehe die Dokumentation der D-Bus-API-Versionierung für Details.

Die Stabilität von GIR-Schnittstellen orientiert sich normalerweise an der C-API-Stabilität, weil sie aus der C-API generiert werden. Eine Komplikation dabei ist, dass deren Stabilität zusätzlich noch von der Version der GObject-Introspektion abhängt, die zur Generierung der GIR verwendet wurde. Die neueren Versionen von GIR haben sich nicht so sehr geändert, weshalb das kein großer Grund zur Besorgnis sein sollte.

# Externe Links

Das Thema API-Stabilität wird in den folgenden Artikeln behandelt:

Wikipedia-Seite zu Programmierschnittstellen

Wikipedia-Seite zu Binärschnittstellen

Dokumentation zur Versionierung der D-Bus-API