Frage Best Practices für die API-Versionierung? [geschlossen]


Gibt es bekannte Vorgehensweisen oder Best Practices für die Webdienst-REST-API-Versionierung?

Ich habe bemerkt, dass AWS versioniert die URL des Endpunkts. Ist dies der einzige Weg oder gibt es andere Möglichkeiten, dasselbe Ziel zu erreichen? Wenn es mehrere Wege gibt, welche Vorteile hat jeder Weg?


878
2017-12-23 15:32


Ursprung


Antworten:


Das ist eine gute und knifflige Frage. Das Thema von URI-Design ist gleichzeitig der prominenteste Teil einer REST-API unddaher möglicherweise langfristiges Engagement gegenüber den Nutzern dieser API.

Da die Entwicklung einer Anwendung und in geringerem Maße ihre API eine Tatsache des Lebens ist und der Entwicklung eines scheinbar komplexen Produkts wie einer Programmiersprache sogar ähnlich ist, hat die URI-Design sollte weniger haben natürliche Einschränkungen und es sollte im Laufe der Zeit erhalten bleiben. Je länger die Lebensdauer der Anwendung und der API ist, desto größer ist das Engagement für die Benutzer der Anwendung und der API.

Auf der anderen Seite ist eine Tatsache, dass es schwierig ist, alle Ressourcen und ihre Aspekte vorherzusehen, die durch die API verbraucht werden. Glücklicherweise ist es nicht notwendig, die gesamte API zu entwerfen, die bis dahin verwendet wird Apokalypse. Es ist ausreichend, alle Ressourcenendpunkte und das Adressierungsschema jeder Ressourcen- und Ressourceninstanz korrekt zu definieren.

Im Laufe der Zeit müssen Sie möglicherweise jeder Ressource neue Ressourcen und neue Attribute hinzufügen, aber die Methode, die API-Benutzer für den Zugriff auf bestimmte Ressourcen verwenden, sollte sich nicht ändern, sobald ein Ressourcenadressierungsschema öffentlich und damit endgültig wird.

Diese Methode gilt für HTTP-Verbsemantiken (z. B. PUT sollte immer aktualisiert / ersetzt werden) und HTTP-Statuscodes, die in früheren API-Versionen unterstützt werden (sie sollten weiterhin funktionieren, sodass API-Clients, die ohne menschliches Eingreifen gearbeitet haben, weiterhin funktionieren können) so wie das).

Darüber hinaus würde das Einbetten der API - Version in den URI das Konzept von Hypermedia als der Motor des Anwendungsstatus (sagte in Roy T. Fieldings Dissertation) durch eine Ressource Adresse / URI, die sich im Laufe der Zeit ändern würde, würde ich schließen, dass API-Versionen sollten nicht lange in Ressourcen-URIs gespeichert werden bedeutet, dass Ressourcen-URIs, auf die sich API-Benutzer verlassen können, sollten Permalinks sein.

Sicher, Es ist möglich, die API-Version in den Basis-URI einzubetten aber nur für sinnvolle und eingeschränkte Anwendungen wie das Debuggen eines API-Clients das funktioniert mit der neuen API-Version. Solche versionierten APIs sollten zeitlich begrenzt sein und nur für begrenzte Gruppen von API-Benutzern (z. B. während geschlossener Betas) verfügbar sein. Andernfalls verpflichten Sie sich, wo Sie nicht sollten.

Ein paar Gedanken zur Wartung von API-Versionen, auf denen das Verfallsdatum liegt. Alle Programmierplattformen / Sprachen, die üblicherweise zur Implementierung von Web-Services (Java, .NET, PHP, Perl, Rails usw.) verwendet werden, ermöglichen eine einfache Bindung von Web-Service-Endpunkten an einen Basis-URI. So ist es einfach sammeln und behalten eine Sammlung von Dateien / Klassen / Methoden trennen Sie über verschiedene API-Versionen.

Von der API-Benutzer-POV ist es auch einfacher, mit einer bestimmten API-Version zu arbeiten und sie zu binden, wenn dies offensichtlich ist, jedoch nur für eine begrenzte Zeit, d. H. Während der Entwicklung.

Aus dem POV des API-Betreuers heraus ist es einfacher, verschiedene API-Versionen parallel zu verwalten, indem Quellcodeverwaltungssysteme verwendet werden, die hauptsächlich an Dateien als kleinste Einheit der Versionsverwaltung (Quellcode) arbeiten.

Bei API-Versionen, die in URI deutlich sichtbar sind, gibt es jedoch eine Einschränkung: Man könnte diesen Ansatz auch ablehnen Der API-Verlauf wird im URI-Design sichtbar / transparent  und daher anfällig für Änderungen im Laufe der Zeit Das widerspricht den Richtlinien von REST. Ich stimme zu!

Um diesen vernünftigen Einwand zu umgehen, implementieren Sie die neueste API-Version unter Versions-API-Basis-URI. In diesem Fall können API-Cliententwickler wählen zwischen:

  • Entwickeln Sie sich gegen das Neueste (indem Sie sich verpflichten, die Anwendung so zu pflegen, dass sie vor eventuellen API-Änderungen geschützt wird, die deren Funktionalität beeinträchtigen könnten schlecht entworfener API-Client).

  • binden an eine bestimmte Version der API (die offensichtlich wird), aber nur für eine begrenzte Zeit

Wenn beispielsweise API v3.0 die neueste API-Version ist, sollten die folgenden zwei Aliase sein (d. H. Sich identisch mit allen API-Anfragen verhalten):

http: // shonzilla / api / Kunden / 1234
http: // shonzilla / api/ v3.0/ Kunden / 1234
http: // shonzilla / api/ v3/ Kunden / 1234

Darüber hinaus versuchen API - Clients, auf die alt Die API sollte darüber informiert werden, dass sie die neueste API-Version verwendet. wenn die von ihnen verwendete API-Version veraltet ist oder nicht mehr unterstützt wird. So greifen Sie auf einen der veralteten URIs wie diese zu:

http: // shonzilla / api/ V2.2/ Kunden / 1234
http: // shonzilla / api/ V2.0/ Kunden / 1234
http: // shonzilla / api/ v2/ Kunden / 1234
http: // shonzilla / api/ v1.1/ Kunden / 1234
http: // shonzilla / api/ v1/ Kunden / 1234

sollte eines der 30x HTTP-Statuscodes, die die Umleitung anzeigen die in Verbindung mit verwendet werden Location HTTP-Header, der zur entsprechenden Version der Ressourcen-URI umleitet, die diese bleiben soll:

http: // shonzilla / api / Kunden / 1234

Es gibt mindestens zwei Umleitungs-HTTP-Statuscodes, die für API-Versionszenarien geeignet sind:

  • 301 Dauerhaft verschoben Angeben, dass die Ressource mit einem angeforderten URI dauerhaft in einen anderen URI verschoben wird (der ein Ressourceninstanzpermallink sein sollte, der keine API-Versionsinformationen enthält). Dieser Statuscode kann verwendet werden, um eine veraltete / nicht unterstützte API-Version anzugeben, die den API-Client darüber informiert, dass a Versionierte Ressourcen-URI wurde durch einen Ressourcen-Permalink ersetzt.

  • 302 gefunden Angeben, dass sich die angeforderte Ressource vorübergehend an einem anderen Speicherort befindet, während der angeforderte URI möglicherweise weiterhin unterstützt wird. Dieser Statuscode kann nützlich sein, wenn die versionslosen URIs vorübergehend nicht verfügbar sind und eine Anforderung mit der Umleitungsadresse wiederholt werden sollte (z. B. mit der eingebetteten APi-Version auf den URI) und wir den Clients mitteilen wollen, dass sie weiterhin verwendet werden sollen Permalinks).

  • Andere Szenarien finden Sie in Redirection 3xx Kapitel der HTTP 1.1-Spezifikation


684
2017-12-29 20:24



Die URL sollte NICHT die Versionen enthalten. Die Version hat nichts mit "Idee" der Ressource zu tun, die Sie anfordern. Sie sollten versuchen, die URL als einen Weg zu dem gewünschten Konzept zu betrachten - nicht so, wie Sie das Element zurückgeben möchten. Die Version diktiert die Darstellung des Objekts, nicht das Konzept des Objekts. Wie andere Poster gesagt haben, sollten Sie das Format (einschließlich der Version) im Anforderungsheader angeben.

Wenn Sie sich die vollständige HTTP-Anfrage für die URLs anschauen, die Versionen haben, sieht das so aus:

(BAD WAY TO DO IT):

http://company.com/api/v3.0/customer/123
====>
GET v3.0/customer/123 HTTP/1.1
Accept: application/xml

<====
HTTP/1.1 200 OK
Content-Type: application/xml
<customer version="3.0">
  <name>Neil Armstrong</name>
</customer>

Der Header enthält die Zeile, die die gewünschte Darstellung enthält ("Accept: application / xml"). Hier sollte die Version gehen. Jeder scheint zu beschönigen die Tatsache, dass Sie das gleiche in verschiedenen Formaten möchten und dass der Client in der Lage sein sollte zu fragen, was es will. Im obigen Beispiel fragt der Client nach IRGENDEIN XML-Darstellung der Ressource - nicht wirklich die wahre Darstellung dessen, was sie will. Der Server könnte theoretisch etwas zurückgeben, das völlig unabhängig von der Anfrage ist, solange es XML ist, und es müsste geparst werden, um zu erkennen, dass es falsch ist.

Ein besserer Weg ist:

(GOOD WAY TO DO IT)

http://company.com/api/customer/123
===>
GET /customer/123 HTTP/1.1
Accept: application/vnd.company.myapp.customer-v3+xml

<===
HTTP/1.1 200 OK
Content-Type: application/vnd.company.myapp-v3+xml
<customer>
  <name>Neil Armstrong</name>
</customer>

Nehmen wir einmal an, die Kunden halten XML für zu ausführlich und wollen stattdessen JSON. In den anderen Beispielen müssten Sie eine neue URL für den gleichen Kunden haben, damit Sie mit:

(BAD)
http://company.com/api/JSONv3.0/customers/123
  or
http://company.com/api/v3.0/customers/123?format="JSON"

(oder etwas ähnliches). Tatsächlich enthält jede HTTP-Anfrage das von Ihnen gesuchte Format:

(GOOD WAY TO DO IT)
===>
GET /customer/123 HTTP/1.1
Accept: application/vnd.company.myapp.customer-v3+json

<===
HTTP/1.1 200 OK
Content-Type: application/vnd.company.myapp-v3+json

{"customer":
  {"name":"Neil Armstrong"}
}

Mit dieser Methode haben Sie viel mehr Gestaltungsfreiheit und halten sich tatsächlich an die ursprüngliche Idee von REST. Sie können die Versionen ändern, ohne Clients zu stören, oder die Clients schrittweise ändern, wenn die APIs geändert werden. Wenn Sie aufhören, eine Repräsentation zu unterstützen, können Sie auf die Anfragen mit HTTP-Statuscode oder benutzerdefinierten Codes antworten. Der Client kann außerdem überprüfen, ob die Antwort im richtigen Format vorliegt, und das XML validieren.

Es gibt viele andere Vorteile und ich bespreche einige von ihnen hier auf meinem Blog:    http://thereeisnorightway.blogspot.com/2011/02/versioning-and-types-in-resthttp-api.html

Ein letztes Beispiel, um zu zeigen, wie schlecht die Version in die URL eingefügt werden kann. Nehmen wir an, Sie möchten ein Stück Information im Objekt haben, und Sie haben Ihre verschiedenen Objekte versioniert (Kunden sind v3.0, Bestellungen sind v2.0 und Shipto-Objekt ist v4.2). Hier ist die böse URL, die Sie im Client angeben müssen:

(Another reason why version in the URL sucks)
http://company.com/api/v3.0/customer/123/v2.0/orders/4321/

273
2017-07-19 16:08



Wir fanden es praktisch und nützlich, die Version in die URL zu stellen. Es macht es einfach zu sagen, was Sie auf einen Blick verwenden. Wir machen alias / foo to / foo / (neueste Versionen) für Benutzerfreundlichkeit, kürzere / sauberere URLs, usw., wie die angenommene Antwort nahelegt.

Die Abwärtskompatibilität für immer zu halten, ist oft kostspielig und / oder sehr schwierig. Wir ziehen es vor, über die Ablehnung, Weiterleitungen wie hier vorgeschlagen, Dokumente und andere Mechanismen zu informieren.


99
2018-01-04 20:57



Ich stimme zu, dass die Versionsdarstellung der Ressourcendarstellung besser dem REST-Ansatz folgt ... aber ein großes Problem mit benutzerdefinierten MIME-Typen (oder MIME-Typen, die einen Versionsparameter anhängen) ist die schlechte Unterstützung für das Schreiben in Accept- und Content-Type-Header in HTML und JavaScript.

Zum Beispiel ist es nicht möglich, IMO mit den folgenden Überschriften in HTML5-Formularen zu senden, um eine Ressource zu erstellen:

Accept: application/vnd.company.myapp-v3+json
Content-Type: application/vnd.company.myapp-v3+json 

Dies ist, weil das HTML5 enctype Attribut ist eine Aufzählung, also alles andere als das Übliche application/x-www-formurlencoded, multipart/form-data und text/plain sind ungültig.

... und ich bin mir sicher, dass es in allen HTML4-Browsern unterstützt wird (mit einem laxeren Encytpe-Attribut, aber es wäre ein Browser-Implementierungsproblem, ob der MIME-Typ weitergeleitet wurde)

Aus diesem Grund empfinde ich jetzt den geeignetsten Weg zur Version über den URI, aber ich akzeptiere, dass es nicht der "richtige" Weg ist.


46
2017-10-13 10:51



Setzen Sie Ihre Version in den URI. Eine Version einer API unterstützt die Typen nicht immer von einer anderen, daher ist das Argument, dass Ressourcen lediglich von einer Version in eine andere migriert werden, einfach falsch. Es ist nicht dasselbe wie das Format von XML zu JSON zu wechseln. Die Typen sind möglicherweise nicht vorhanden oder sie haben sich möglicherweise semantisch geändert.

Versionen sind Teil der Ressourcenadresse. Sie leiten von einem API zum anderen. Es ist nicht RESTful, die Adressierung in der Kopfzeile zu verbergen.


21
2018-06-05 15:09



Es gibt einige Stellen, an denen Sie eine Versionierung in einer REST-API vornehmen können:

  1. Wie bereits erwähnt, in der URI. Dies kann handhabbar und sogar ästhetisch ansprechend sein, wenn Umleitungen und dergleichen gut verwendet werden.

  2. Im Header "Accepts:" befindet sich die Version im Dateityp. Wie 'mp3' vs 'mp4'. Dies wird auch funktionieren, obwohl IMO es ein bisschen weniger gut funktioniert als ...

  3. In der Ressource selbst. Bei vielen Dateiformaten sind die Versionsnummern in ihnen eingebettet, normalerweise in der Kopfzeile. Dadurch kann neuere Software "nur funktionieren", indem alle vorhandenen Versionen des Dateityps verstanden werden, während ältere Software stochern kann, wenn eine nicht unterstützte (neuere) Version angegeben wird. Im Kontext einer REST-API bedeutet dies, dass Ihre URIs niemals geändert werden müssen, sondern nur Ihre Antwort auf die bestimmte Version der Daten, die Sie übergeben haben.

Ich kann Gründe sehen, alle drei Ansätze zu verwenden:

  1. wenn Sie gerne neue APIs reinigen oder für größere Versionsänderungen, wo Sie einen solchen Ansatz wünschen.
  2. Wenn Sie möchten, dass der Client vor dem PUT / POST weiß, ob es funktioniert oder nicht.
  3. Wenn es in Ordnung ist, wenn der Client seinen PUT / POST machen muss, um herauszufinden, ob es funktionieren wird.

13
2017-10-24 16:39



Die Versionierung Ihrer REST-API entspricht der Versionierung einer anderen API. Geringfügige Änderungen können vor Ort vorgenommen werden, größere Änderungen erfordern möglicherweise eine ganz neue API. Am einfachsten ist es für Sie, jedes Mal von vorne anzufangen, wenn Sie die Version in die URL einfügen. Wenn Sie dem Client das Leben leichter machen möchten, versuchen Sie, die Rückwärtskompatibilität aufrechtzuerhalten, die Sie mit Deprecation (permanenter Weiterleitung), Ressourcen in verschiedenen Versionen usw. machen können. Dies ist aufwendiger und erfordert mehr Aufwand. Aber es ist auch, was REST in "Coole URIs nicht ändern" ermutigt.

Am Ende ist es wie bei jedem anderen API-Design. Wiegen Sie die Anstrengung gegen den Komfort des Kunden. Erwägen Sie, die semantische Versionierung für Ihre API zu übernehmen, die Ihren Kunden deutlich macht, wie abwärtskompatibel Ihre neue Version ist.


8
2018-03-06 07:16