2012-05-14 11 views
5

Angenommen, ich habe viel über die Versionierung einer erholsamen API gelesen und mich entschieden, den Dienst nicht über die URL zu versionieren, sondern Medientypen (Format und Schema in die Anfrage accept header):Implementieren der Versionsverwaltung einer RESTful-API mit WCF oder ASP.Net Web Api

Was wäre der beste Weg, um einen WCF-Service oder einen Web-API-Dienst zu implementieren, um Anfragen zu beantworten, die die angeforderte Ressource in der URI, dem Format (zB application/json) und dem Schema/Version (zB player-v2) im Accept-Header?

WCF ermöglicht es mir, basierend auf der URI zu routen, aber nicht basierend auf Kopfzeilen. Also kann ich nicht richtig routen.

Web Api ermöglicht mir benutzerdefinierte Mediatypeformatters zu definieren, Routing für das angeforderte Format, aber nicht das Schema (z. B. Rückgabetyp PlayerV1 oder PlayerV2).

Ich mag würde einen Service implementieren (entweder mit WCF oder Web-Api), die für diese Anforderung (Pseudo-Code):

api.myservice.com/players/123 Accept format=application/json; schema=player-v1 

gibt eine PlayerV1 Einheit, im JSON-Format

und für diese Anforderung lautet:

api.myservice.com/players/123 Accept format=application/json; schema=player-v2 

gibt eine PlayerV2-Entität im JSON-Format zurück.

Irgendwelche Tipps zur Umsetzung?

BEARBEITEN: Um zu klären, warum ich Content Negotiation verwenden, um mit Versionen umzugehen, siehe hier: REST API Design: Put the “Type” in “Content-Type”.

Antwort

2

Was Sie hier bringen, sieht für mich nicht wie Versionierung aus, aber es ist mehr von Content-Verhandlungen. Akzeptieren Header drückt Wünsche des Kunden über das Format der Ressource aus. Server sollte die Wünsche erfüllen oder 406 zurückgeben. Wenn wir also mehr von einem Vertragskonzept brauchen (obwohl Web-API-RPC nicht definiert), ist die Verwendung von Ressource fester.

Die Best Practices für die Versionsverwaltung hat noch ausführlich diskutiert werden, aber meisten REST-Enthusiasten glauben, dass die Version in der URL verwendet wird, um die Art und Weise (z http://server/api/1.0.3/...) zu gehen. Dies macht auch mehr Sinn für mich, da in Ihrem Ansatz mit Content-Negotiation-Server Rückwärtskompatibilität beibehalten werden muss und ich kann mir nur vorstellen, dass der Code auf dem Server immer komplexer wird. Mit der Verwendung der URL-Methode können Sie eine saubere Pause einlegen: Alte Clients können früher erfolgreich verwenden, während neue Clients die Vorteile der neuen API nutzen können.


UPDATE

OK, jetzt hat sich die Frage "Umsetzung content-Verhandlungen in einer RESTful AP" geändert.

Typ 1: Controller-vergesslich

Grundsätzlich, wenn Content-Negotiation nur das Format der Ressource beinhaltet, Implementierung oder den richtigen Medientyp Formatierer ist genug. Wenn die Inhaltsverhandlung beispielsweise die Rückgabe von JSON oder XML umfasst. In diesen Fällen ist Controller zu Inhaltsverhandlungen blind.

Typ 2: Controller-aware

muss Steuerung Kenntnis von der Anforderung Verhandlung sein. In diesem Fall müssen Parameter aus der Anfrage aus der Anfrage extrahiert und als Parameter übergeben werden. Zum Beispiel, lassen Sie sich diese Aktion auf einem Controller vorstellen:

public Player Get(string schemaVersion) 
{ 
    ... 
} 

In diesem Fall würde ich klassischen MVC Stil Wert Provider (Siehe Brad Wilson's post on ValueProviders - das ist auf MVC aber Wert Provider Web-API sieht ähnlich) verwenden:

public Player Get([ValueProvider(typeof(RequestHeadersSchemaValueProviderFactory))]string schemaVersion) 
{ 
    ... 
} 
+2

Beginnen wir nicht mit einer Diskussion darüber, welcher Weg besser ist (Version in URI oder nicht), da das hier nicht der Punkt ist. Ich könnte die Frage umformulieren: "Implementierung von Content-Negotiation in einer RESTful-API ..", die Implementierungsherausforderung wäre immer noch die gleiche, oder? – codeclash

+0

@kardinal Ich habe aktualisiert. – Aliostad

+0

Der Wertanbieter würde mir Zugriff auf das angeforderte Schema geben, aber in jedem Fall wäre der Rückgabetyp in Ihrem Beispiel Player, während ich tatsächlich je nach dem angeforderten Schema entweder einen Player oder PlayerV2, ... zurückgeben müsste. Fehle ich etwas? – codeclash