Web Api Response Versionierungslösung?

9

Bevor Sie dies als Duplikat betrachten, nehmen Sie sich bitte eine Sekunde Zeit. Wenn ich Web Api über die Versionierung recherchiere, ist alles um versionierte Controller und Best Practices zur Angabe der Version in URL vs. Headern besorgt.

Was ich herausfinden möchte, ist der beste Weg, die Ausgabeantwort zu versionieren, damit ich nicht die Clients der Version 1 durchbruche, wenn ich mit Version 2 herauskomme.

Nehmen wir an, ich habe eine sich ständig ändernde DAL für eine Website-Suite, die eine Website und andere Dienste versorgt. Ich arbeite an einem neuen Web-API-Projekt, das Antworten enthalten sollte, die versionierten Schemas entsprechen.

Meine Frage ist: Was sind bewährte Lösungen / Best Practices für die Implementierung von Versionsverwaltung in Web Api Projekten, die hinter versionierten Controllern und vor un-versionierten DALs liegen?

Ich habe eine Lösung entwickelt, die eine zusätzliche Ebene versionierter Repositorys und eine zusätzliche Schicht versionierter Modelle enthält, sodass die versionierten Controller versionierte Repositorys verwenden, die versionierte Modelle verwenden. Und ich habe Automapper eingerichtet, um zwischen den nicht versionierten Domänenmodellen (von der DAL) zu den versionierten Modellen zu mappen. Aber der Fehler dieses Setup ist, ich muss alle Karten für jede neue Version aktualisieren; ein exponentiell wachsendes Problem.

Es muss einen besseren Weg geben. Danke!

    
Levitikon 25.03.2013, 14:57
quelle

2 Antworten

2

Nach meiner Erfahrung besteht die sauberste (aber nicht die einfachste) Lösung aus fünf Teilen:

  1. Ein autorisierendes Datenmodell und ein immer aktuelles Backend: DAL / Database / Services.
  2. Mit versionsspezifischen Daten, die für das System verständlich sind: Multiple Data Model.
  3. Sicherstellen, dass Änderungen zwischen den Versionen erkannt und ordnungsgemäß nachverfolgt werden und dass Änderungen reversibel sind. Regeln müssen explizit definiert werden, um das zu handhaben (das könnte schwieriger sein): Konverter.
  4. Dem Client wird explizit mitgeteilt, welche Version er verwendet: Query Strings / Header.
  5. Verfügen über eine autoritative Geschäftslogik, die immer auf dem neuesten Stand ist, aber zwischen verschiedenen Datenversionen wechseln kann - abwärtskompatibel: Controller.

Das Datenmodell, das wir haben, ist Lieferant zum Beispiel.

(1) Das Back-End (d. h. DAL / Datenbank) ist bei V5. Die Geschäftslogik (d. H. Dienste) befindet sich ebenfalls bei V5.

(2) Wir müssen jedoch gleichzeitig den Client-Lieferanten für V1, V2, V3, V4 und den aktuellen Client für V5 bedienen. Lassen Sie uns V1 zu V5 unseres Datenmodells machen: SupplierV1, SupplierV2 ... (Sie könnten Namespace oder andere Möglichkeiten verwenden, um sie zu unterscheiden)

(3) Sie müssen Konverter definieren und verwalten. Sie müssen sowohl Vorwärts- als auch Rückwärtskompatibilität zwischen Datenmodellversionen verarbeiten. Dies könnte mit einem Strategie-Pattern, Lambdas, einem Manager mit DI-Konvertern, etc. getan werden. Sie müssten aber V1- & gt; V2- & gt; V3- & gt; V4- & gt; V5 aber auch V5- & gt; V4- & gt; V3- & gt; V2- & gt; V1 .

Regeln in den Konvertern sind der schwierigste Teil. Manchmal ist es einfach - Standardwerte für neue Felder. Zu anderen Zeiten müssen Sie eine Geschäftslogik ausführen. Manchmal müssen Sie vorhandene Daten konvertieren / zusammenführen; Sie müssen sicherstellen, dass es reversibel ist! Wenn zum Beispiel die Werte in V1 gemischt sind und Sie sie in V2 in Großbuchstaben umwandeln, können Sie sie nicht auf V1 zurückversetzen, da Sie nicht wissen, welche Zeichen Groß- und Kleinbuchstaben sind. Du könntest diese zwei Wege behandeln:

  • Halte es in Großbuchstaben für V1. Afterall, es ist nur V2, die es erfordert, V1 kann wahrscheinlich mit allen großen Fällen arbeiten (offensichtlich würde nicht auf Schlüssel funktionieren).
  • Behalten Sie den alten Wert in einem Feld in V2 bei. Wenn Sie sich beispielsweise entschieden haben, das Feld "State" in Großbuchstaben zu schreiben, können Sie einen OriginalState mit Groß- und Kleinschreibung beibehalten und ihn in State kopieren, wenn Sie zu V1 zurückkehren.

Wie Sie sehen können, müssen Sie über diese harten und es ist oft nicht trivial denken.

(4) In Controllern müssen Sie dann wissen, mit welcher Version der Client arbeitet, um bei Bedarf die Konvertierung in und aus dem Controller auszuführen. Dazu könnten Sie Abfragezeichenfolgen, Header (X-API-Version oder Accept zum Beispiel, aber Vorsicht einige Host / Proxy-Strips einige von ihnen), Post-Parameter, etc.

(5) Wenn der Controller schließlich ein Datenmodell empfängt, müssen Sie prüfen, welche Version der Client gesendet hat (sagen wir V2) und auf die neueste Version für das Back-End aufrüsten (V5 ). Verwenden Sie es anschließend ordnungsgemäß. Wenn Sie anschließend Daten zurücksenden müssen, müssen Sie sie auf die Clientversion (V2) herabstufen. Um dies zu tun, könnten Sie benutzerdefinierte Bindung, benutzerdefinierte Anfrage Aktionen, benutzerdefinierte Aktion Ergebnisse, etc. Zum Beispiel (bitte automatisieren Sie das):

%Vor%

Dies ist eine sehr grobe Art, Ihnen die Idee zu zeigen. Das haben wir in einem unserer Systeme gemacht. Sie könnten Manager haben, die Typen und Versionen erkennen und die Konvertierung selbst durchführen, Sie könnten Assembly / Converter dynamisch mit Dependency Injection laden, Sie könnten den Großteil der Conversion in benutzerdefinierten Bindings / Request-Aktionen automatisieren, und so weiter.

Hinweis: Es gibt auch einen Teil (6) , den Sie möglicherweise berücksichtigen müssen. Um die Client-Daten in Ihrer Datenbank tatsächlich auf V5 zu aktualisieren, können Sie dies bei der Migration zu V5 (Stapelmigration von Daten) oder zur Laufzeit tun. Wenn Sie SupplierV1 erhalten, laden Sie dieses aus Ihrer Datenbank (noch V1-Daten), führen das Upgrade auf V5 durch und speichern die aktualisierten Daten im Converter. Das bedeutet, dass Sie Ihr Backend jetzt direkt migrieren können. Offensichtlich ist es nicht so einfach wie es klingt, da Sie beide Versionen in derselben Datenbank unterstützen müssen, aber je nach Art der Änderungen oder Daten, die Sie haben, gut funktionieren.

    
Karhgath 10.01.2014, 18:08
quelle
0

Ich würde vorschlagen, Ihre Modelle zu versionieren. Sie können dies nach Namespace tun, um die Dinge einfach zu halten. In der Tat macht NServiceBus etwas Ähnliches für seine Nachrichtenübermittlung. Hier ist ihr Beispiel: Ссылка

    
Ryan Cromwell 29.03.2013 14:21
quelle