API-Versionierung: Breaking Changes sauber steuern

Wie wir API-Versionierung pragmatisch aufbauen, Breaking Changes absichern und Deprecation, Sunset, Doku und Contract Tests zusammen denken.

Letzte Änderung: 23. März 2026

API-Versionierung: Breaking Changes sauber steuern

API-Versionierung ist keine Frage von Geschmack. Sie wird relevant, sobald Änderungen das Verhalten für bestehende Clients brechen können. Dann geht es nicht mehr nur um saubere Technik, sondern um Zuverlässigkeit, Kommunikation und planbare Migration.

Wir erleben oft zwei Extreme: Entweder wird gar nicht versioniert und jede Änderung landet einfach in derselben API, oder es entstehen neue Versionen ohne klare Regeln, Doku und Übergangsprozess. Beides sorgt langfristig für Reibung.

Wann eine neue API-Version sinnvoll ist

Eine neue Version braucht es immer dann, wenn bestehende Clients ihr Verhalten ändern müssten, um weiter korrekt zu funktionieren.

Typische Beispiele sind:

  • ein Feld wird entfernt oder umbenannt
  • ein Datentyp ändert sich, zum Beispiel von String zu Array
  • ein bisher optionales Feld wird verpflichtend
  • ein Statuscode bekommt eine neue Bedeutung
  • Standardverhalten bei Filtern, Sortierung oder Paging ändert sich

Wenn du dagegen nur neue optionale Felder ergänzt oder Dokumentation verbesserst, reicht meist ein normales Release ohne neue Version.

Was gute Versionierung leisten muss

Eine gute Versionierungsstrategie beantwortet vier Fragen klar:

  1. Woran erkennen Clients ihre Version?
  2. Wann ist eine neue Version nötig?
  3. Wie lange bleibt eine alte Version unterstützt?
  4. Wie begleiten wir Migration und Abschaltung?

Ohne diese Antworten entsteht Unsicherheit, selbst wenn die technische Umsetzung zunächst funktioniert.

Pfad oder Header, was wir empfehlen

Es gibt zwei gängige Wege: Versionierung über den Pfad oder über den Accept-Header.

Version im Pfad

Beispiele wie /v1/orders oder /v2/orders sind sichtbar, leicht zu debuggen und für Gateways, Caching und Doku meist einfacher zu handhaben.

Wir empfehlen diesen Weg besonders für:

  • öffentliche APIs
  • APIs mit vielen externen Integrationen
  • Teams, die schnelle Nachvollziehbarkeit im Alltag brauchen

Version über den Header

Header-basierte Versionierung hält URLs stabil, macht die Nutzung aber weniger sichtbar. Für interne oder stark kontrollierte Clients kann das gut funktionieren, erfordert aber mehr Disziplin in Doku, Tests und Monitoring.

Wir nutzen diesen Ansatz eher dann, wenn:

  • Clients zentral gesteuert werden,
  • API-Gateways sauber konfiguriert sind,
  • und das Team Erfahrung mit medientypbasierter Versionierung hat.

Unsere praktische Entscheidungsregel

Für öffentliche und partnergenutzte APIs bevorzugen wir Pfad-Versionierung. Für interne Plattformen mit kontrollierten Clients kann Header-Versionierung sinnvoll sein.

Wichtiger als die Technik ist aber, dass ihr euch verbindlich auf einen Weg festlegt und ihn über alle Services hinweg konsistent durchzieht.

Versionierung braucht Doku und Tests

Eine neue Version ohne begleitende Dokumentation ist nur halb fertig. Jede API-Version braucht aus unserer Sicht mindestens:

  • eine klar erkennbare OpenAPI-Dokumentation
  • Beispiele für Requests und Responses
  • eine Beschreibung der Breaking Changes
  • Hinweise zur Migration
  • Contract Tests für kritische Verbraucher

Gerade Contract Tests helfen, versehentliche Brüche früh sichtbar zu machen, bevor Partner oder Frontends betroffen sind.

Deprecation und Sunset sauber kommunizieren

Viele Probleme entstehen nicht beim Start einer neuen Version, sondern beim Ende der alten. Deshalb trennen wir sauber zwischen Deprecation und Abschaltung.

  • Deprecation bedeutet: Diese Version bleibt vorerst nutzbar, sollte aber nicht mehr neu verwendet werden.
  • Sunset bedeutet: Ab diesem Datum wird die Version abgeschaltet.

Ein belastbarer Ablauf sieht so aus:

  1. Breaking Change bewerten und neue Version anlegen.
  2. Alte Version in Doku und OpenAPI als deprecated markieren.
  3. Sunset-Datum sichtbar kommunizieren.
  4. Migrationshinweise und Beispiele bereitstellen.
  5. Nutzung der alten Version messen und betroffene Clients aktiv begleiten.
  6. Abschaltung mit klarer Fehlermeldung durchführen.

Beispiel mit Api Platform

Wenn du mit Symfony und Api Platform arbeitest, lässt sich Versionierung gut strukturiert umsetzen.

Variante 1: Version im Pfad

<?php
 
namespace App\Entity;
 
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use Symfony\Component\Serializer\Annotation\Groups;
 
#[ApiResource(
    routePrefix: '/v1',
    operations: [new Get(), new GetCollection()],
    normalizationContext: ['groups' => ['book:read:v1']]
)]
#[ApiResource(
    routePrefix: '/v2',
    operations: [new Get(), new GetCollection()],
    normalizationContext: ['groups' => ['book:read:v2']]
)]
class Book
{
    #[Groups(['book:read:v1', 'book:read:v2'])]
    public string $title;
 
    #[Groups(['book:read:v2'])]
    public string $isbn;
}

Das funktioniert gut, wenn URLs klar unterscheidbar sein sollen und du die Version auch in Logs, Support und Dokumentation sofort sehen willst.

Variante 2: Version über den Accept-Header

api_platform:
  formats:
    json_v1: ['application/vnd.xebro.v1+json']
    json_v2: ['application/vnd.xebro.v2+json']
<?php
 
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
 
#[ApiResource(
    operations: [
        new Get(outputFormats: ['json_v1' => ['application/vnd.xebro.v1+json']]),
        new GetCollection(outputFormats: ['json_v1' => ['application/vnd.xebro.v1+json']]),
    ],
    normalizationContext: ['groups' => ['book:read:v1']]
)]
#[ApiResource(
    operations: [
        new Get(outputFormats: ['json_v2' => ['application/vnd.xebro.v2+json']]),
        new GetCollection(outputFormats: ['json_v2' => ['application/vnd.xebro.v2+json']]),
    ],
    normalizationContext: ['groups' => ['book:read:v2']]
)]
class Book
{
    // Felder wie oben
}

Und ein Request dazu:

curl -H 'Accept: application/vnd.xebro.v2+json' https://api.xebro.de/books/1

Deprecation-Header technisch ergänzen

Wenn eine ältere Version ausläuft, helfen sichtbare Header zusätzlich zur Doku.

<?php
 
namespace App\Api;
 
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
 
final class DeprecationHeadersSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [KernelEvents::RESPONSE => 'onResponse'];
    }
 
    public function onResponse(ResponseEvent $event): void
    {
        $response = $event->getResponse();
        $response->headers->set('Deprecation', 'true');
        $response->headers->set('Sunset', 'Sat, 30 Aug 2025 00:00:00 GMT');
        $response->headers->set('Link', '<https://docs.xebro.de/api/migration>; rel="sunset"');
    }
}

Zusätzlich kann die alte Operation in OpenAPI sichtbar als deprecated markiert werden.

<?php
 
use ApiPlatform\Metadata\Get;
 
new Get(
    openapiContext: [
        'deprecated' => true,
        'summary' => 'V1 wird ab 30.08.2025 abgeschaltet'
    ]
);

Typische Fehler bei der API-Versionierung

  • Breaking Changes werden als normale Releases behandelt
  • die neue Version ist online, aber die Dokumentation bleibt unklar
  • Sunset-Daten fehlen oder werden nie aktiv kommuniziert
  • Tests decken nur die neue Version ab
  • alte Versionen bleiben aus Unsicherheit dauerhaft aktiv

Diese Fehler führen selten sofort zum Ausfall, aber fast immer zu unnötiger Komplexität und steigenden Betriebskosten.

Unsere Checkliste für ein sauberes Major Release

  • Breaking Change fachlich bewertet
  • Versionierungsweg klar gewählt
  • OpenAPI und Beispiele aktualisiert
  • Contract Tests für kritische Clients aktiv
  • Deprecation und Sunset kommuniziert
  • Migrationspfad dokumentiert
  • Monitoring für alte und neue Version vorhanden

Passende nächste Inhalte

Wenn du vor einer neuen API-Version stehst oder eine alte Version endlich kontrolliert ablösen willst, helfen wir dir dabei, Regeln, Doku und Delivery so aufzusetzen, dass der Wechsel planbar bleibt.