REST-API-Versionierung: URL, Header oder Query, was passt
6 Min. Lesezeit
REST-API-Versionierung ist die Art, wie eine API einem Aufrufer mitteilt, welchen Vertrag eine Anfrage nutzt, damit der Server den Vertrag ändern kann, ohne Aufrufer zu brechen, die noch nicht umgezogen sind. Die Version kann an drei Stellen stehen: im URL-Pfad (/v2/orders), in einem Request-Header (Accept: application/vnd.acme.v2+json oder ein eigener Api-Version: 2026-10-01) oder in einem Query-Parameter (/orders?version=2). Der Pfad ist am verbreitetsten, weil er überall sichtbar ist, der Header ist die sauberste Lösung für die URL, und der Query-String ist die, die die meisten Teams bereuen. Was passt, hängt davon ab, wer eure Aufrufer sind und wie ihr sie über Änderungen informieren wollt.
| Wo die Version steht | Beispiel | Sichtbar für | Standardmäßig cachebar | Genutzt von |
|---|---|---|---|---|
| URL-Pfad | GET /v2/orders | Jedes Log, jeden Link, Proxy und Browser | Ja | Twitter, Shopify, die meisten öffentlichen APIs |
| Eigener Header | Api-Version: 2026-10-01 | Nur Clients, die ihn setzen | Mit Vary: Api-Version | Stripe (Stripe-Version), GitHub (X-GitHub-Api-Version) |
| Accept-Header | Accept: application/vnd.acme.v2+json | Nur Clients, die ihn setzen | Mit Vary: Accept | GitHub-Media-Types, manche Enterprise-APIs |
| Query-Parameter | GET /orders?api-version=2 | Logs und Links, vermischt mit Filtern | Ja, verschmutzt aber Cache-Schlüssel | Azure-REST-APIs |
| Keine Version | GET /orders plus nur additive Änderungen | Niemanden | Ja | Interne und GraphQL-artige APIs |
Was sind v1 und v2 in einer REST-API?
v1 und v2 sind Namen für zwei Versionen des API-Vertrags: dieselben Ressourcen, erreichbar unter verschiedenen Pfaden, wobei v2 Felder umbenennen, Typen ändern, Endpunkte streichen oder Fehlerformate verändern darf, auf die v1-Aufrufer angewiesen sind. Eine Anfrage an /v1/orders bekommt weiter die alte Form, solange v1 unterstützt wird; eine Anfrage an /v2/orders bekommt die neue. Die Zahl ist ein Versprechen über Kompatibilität, und das Versprechen ist das, was sie nützlich macht. Sie bei jedem Release zu erhöhen, macht aus dem Namen Rauschen.
Die meisten APIs brauchen eine neue Hauptversion nur für eine Änderung, die bestehende Aufrufer bricht. Ein Feld, ein neuer Endpunkt oder ein neuer optionaler Parameter kann unter der aktuellen Version ausgeliefert werden, weil ein gut geschriebener Client ignoriert, was er nicht kennt. Wann man eine API versioniert, und was man stattdessen tut behandelt die Entscheidung; dieser Artikel handelt davon, wo die Version bei REST-API-Versionierung steht, sobald ihr euch für einen Sprung entschieden habt.
Gehört die REST-API-Versionierung in die URL oder in einen Header?
Legt sie in die URL, wenn eure Aufrufer Menschen einschließen, die Anfragen in einen Browser tippen, Beispiele aus der Dokumentation kopieren oder Logs lesen; legt sie in einen Header, wenn ihr eine stabile URL pro Ressource wollt und eure Aufrufer alle SDKs oder Code sind, den ihr kontrolliert. Der URL-Pfad ist explizit wie nichts anderes: Ein Support-Ticket mit der Request-Zeile darin verrät euch die Version schon. Ein Header muss bei jeder Anfrage gesetzt werden, ist in einem Link unsichtbar und geht an einem Proxy leicht verloren, weshalb header-versionierte APIs immer einen Standard für Anfragen definieren, die keinen senden.
Der Header-Ansatz hat über aufgeräumte URLs hinaus einen echten Vorteil: Er trennt die Identität der Ressource von ihrer Darstellung, und genau so wurde HTTP entworfen. RFC 9110 beschreibt Content Negotiation über Accept, und ein Media-Type wie application/vnd.github.v3+json ist eine so ausgedrückte Version. In der Praxis zählt die Reinheit des Entwurfs weniger als die Frage, ob eure Aufrufer daran denken, den Header zu senden.
Wie funktioniert datumsbasierte Versionierung?
Statt v1 und v2 ist die Version ein Datum, und jeder Breaking Change bekommt ein neues Datum. Ein Aufrufer pinnt das Datum, gegen das er integriert hat, meist einmal auf Kontoebene, und behält dieses Verhalten, bis er sich für einen Umzug entscheidet. Stripes Stripe-Version-Header und GitHubs X-GitHub-Api-Version funktionieren beide so.
Der Preis liegt in der Implementierung. Jeder Breaking Change wird zu einer kleinen Übersetzungsschicht, die zwischen dem gepinnten Datum und der aktuellen Form umwandelt, und der Server stapelt sie: Eine Anfrage, die zwei Jahre zurück gepinnt ist, durchläuft jede Änderung seitdem. Das ist schwerer zu bauen als eine zweite Kopie der Handler, und es belohnt eine API, die sich selten ändert. Teams, die einen Breaking Change pro Monat ausliefern, landen bei Dutzenden von Transformationen. Stripe-API-Versionierung betrachtet das Modell aus Sicht des Aufrufers, einschließlich dessen, was der Changelog tragen muss.
Warum wird von Query-String-Versionierung abgeraten?
Weil sie den Vertrag mit den Filtern vermischt. /orders?status=open&api-version=2 lässt die Version wie eine optionale Verfeinerung aussehen statt wie das, was die Form jedes Felds in der Antwort bestimmt. Sie ist auch die, die man am leichtesten versehentlich verliert, denn Query-Strings werden von Client-Bibliotheken neu gebaut, von manchen Proxys entfernt und von Menschen von Hand bearbeitet. Microsofts eigener Leitfaden zum REST-API-Design dokumentiert die Query-Parameter-Form, die Azure nutzt, und das Ökosystem generierter SDKs darum herum ist das, was sie tragbar macht; ohne diese Werkzeuge bekommt ein Aufrufer, der den Parameter vergisst, stillschweigend die Standardversion.
Was passiert mit der alten Version?
Sie läuft weiter, mit einem Datum, an dem sie endet. Der Sinn von Versionierung ist, Aufrufer nach ihrem eigenen Zeitplan umziehen zu lassen, und das stimmt nur, wenn die alte Version lange genug verfügbar bleibt und sie erfahren, wann sie endet. Googles Leitfaden zur API-Versionierung beschreibt den Lebenszyklus, den Google für seine eigenen APIs nutzt: Eine stabile Version wird bis zu einem veröffentlichten Abkündigungsdatum unterstützt, und der Ersatz ist während des gesamten Abkündigungsfensters verfügbar.
Die Ankündigung ist der Teil, den die meisten Teams zu knapp bauen. Ein neuer Pfad oder Header nützt nur Aufrufern, die wissen, dass er existiert, was sich geändert hat und wann v1 verschwindet. Das sind drei Fakten, und jeder braucht einen Ort: ein datierter Eintrag im API-Changelog mit den Unterschieden auf Feldebene, eine Deprecation-Ankündigung, die das Enddatum nennt, und ein Migrationsleitfaden, der einen Aufrufer auf der alten Version durch jede Änderung führt. Eine API-Version abschalten behandelt den letzten Schritt, einschließlich des Sunset-Headers, über den ein Client das Datum auf jeder Antwort erkennt.
Kann man REST-API-Versionierung ganz vermeiden?
Ja, solange jede Änderung additiv ist. Fügt Felder hinzu, entfernt oder benennt sie nie um; fügt Endpunkte hinzu, ändert nie, was ein bestehender zurückgibt; akzeptiert neue optionale Parameter, ändert nie die Bedeutung eines alten. Viele interne APIs laufen jahrelang allein mit dieser Regel, und es ist die Regel, der GraphQL-Schemata von Haus aus folgen. Der Preis ist ein Vertrag, der nur wächst, mit abgekündigten Feldern, die bleiben müssen, weil irgendjemand irgendwo sie noch liest.
Ist eine additive Änderung unmöglich, ist die Version das Werkzeug. Die Wahl zwischen Pfad, Header und Datum entscheidet, was Aufrufer sehen und wie die Änderung angekündigt wird; konstant bleibt, dass die Änderung irgendwo aufgeschrieben werden muss, wo ein Aufrufer sie liest. Für eine API mit externen Aufrufern ist dieser Ort der Changelog, und der Artikel zu Breaking Changes behandelt, was als einer zählt.
FAQ
Was ist der beste Weg, eine REST-API zu versionieren? Eine Hauptversion im URL-Pfad ist am weitesten verstanden und am schwersten falsch zu machen, was sie zum Standard für eine öffentliche API macht. Eine Header-Version hält URLs stabil und passt zu SDK-getriebenen APIs; ein datumsbasierter Header passt zu APIs, die sich selten ändern und Aufrufer ihr Verhalten pinnen lassen wollen.
Was ist v1 in einer API-URL?
Es ist die erste Hauptversion des API-Vertrags. Anfragen an /v1/... wird die für Version 1 dokumentierte Form zugesichert, auch nachdem ein /v2/ mit anderen Feldern oder anderem Verhalten existiert.
Brauche ich für jede Änderung eine neue API-Version? Nein. Additive Änderungen wie neue Felder, Endpunkte und optionale Parameter können unter der bestehenden Version ausgeliefert werden. Nur eine Änderung, die bestehende Aufrufer bricht, braucht eine neue.
Wie lange sollte eine alte API-Version unterstützt werden? Lange genug, damit Aufrufer migrieren können, was bei einer öffentlichen API meist sechs bis zwölf Monate nach Verfügbarkeit des Ersatzes sind, mit dem Datum, das bei der Ankündigung veröffentlicht und in der Deprecation-Ankündigung wiederholt wird.
Die technischen Aussagen in diesem Artikel wurden nicht unabhängig geprüft. Wenn etwas nicht stimmt, sagen Sie es uns, und wir korrigieren es.