In meiner Erfahrung ist die sauberste (aber nicht am einfachsten) Lösung, die wir kommt in 5 Teilen gefunden:
- ein maßgebliches Datenmodell und ein hinteres Ende, das immer auf dem neuesten Stand : DAL/Datenbank/Dienste.
- Mit versionsspezifischen Daten alle für das System verständlich: Multiple Data Model.
- Sicherstellen, dass Änderungen zwischen Versionen identifiziert 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.
- Lassen Sie den Client explizit sagen, welche Version sie verwenden: Query Strings/Header.
- Verfügt ü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 Backend (d. H. DAL/Datenbank) ist auf V5. Die Geschäftslogik (d. H. Dienste) befindet sich ebenfalls bei V5.
(2) Allerdings müssen wir Client Supplier auf V1, V2, V3, V4 und aktuellen Client auf V5 alle zur gleichen Zeit 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 usw. erfolgen.Sie müßten mit V1-> V2-> V3-> V4-> V5 aber auch mit V5-> V4-> V3-> V2-> V1 umgehen.
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. Sie können diese zwei Möglichkeiten behandeln:
- Halten Sie 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 Tasten arbeiten).
- Behalten Sie den alten Wert in einem Feld in V2. Wenn Sie beispielsweise beschlossen haben, das Feld "State" in Großbuchstaben zu setzen, können Sie einen OriginalState beibehalten, der Groß- und Kleinschreibung enthält, und ihn in State kopieren, wenn Sie zu V1 zurückkehren.
Wie Sie sehen können, müssen Sie über diejenigen hart nachdenken und es ist oft nicht trivial.
(4) Dann müssen Sie in Controllern 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) Schließlich, wenn die Controller empfängt ein Datenmodell, Sie müssen überprüfen, welche Version der Client gesendet hat (sagen wir V2) und auf die neueste Version für das Back-End (V5) aktualisieren. 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 tun benutzerdefinierte Bindung, individuelle Anfrage Aktionen, benutzerdefinierte Aktion Ergebnisse, etc. Zum Beispiel (bitte nicht automatisieren, dass):
public IHttpActionResult DoSomethingWithSupplier(JToken supplier) // Receiving Json Supplier
{
// TODO: Get the client version type, for example in the X-API-Version header/query strings
// (beware, some proxy/hosts strips some headers)
// Type clientType = ...
var clientSupplier = JsonConvert.DeserializeObject(supplier.ToString(), clientType);
// You should probably detect latest version automatically (instead of typeof)
var latestSupplier = VersionManager.Upgrade(clientSupplier, clientType, typeof(SupplierV5));
outputSupplier = DoSomething(latestSupplier);
// You should probably detect latest version automatically (instead of typeof)
var clientOutputSupplier = VersionManager.Downgrade(outputSupplier, typeof(SupplierV5), clientType);
return Ok(clientOutputSupplier);
}
Dies ist eine sehr grobe Art und Weisen 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 Bindungen/Request-Aktionen automatisieren und so weiter.
Hinweis: Es gibt auch einen Teil (6) müssen Sie möglicherweise prüfen. 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 der Art der Änderungen oder Daten, die Sie haben, gut für Sie arbeiten können.
https://github.com/Sebazzz/Sdammann.WebApi.Versioning – adt
Es ist eine großartige Lösung für die Versionsverwaltung Controller, aber wie ich schon sagte, ich bin nicht auf der Suche nach diesem – Levitikon
Das einzige, was ich mir vorstellen konnte; wäre, ein eigenständiges Modell zu erstellen, das diese Daten enthält. Verwenden Sie dann einen Controller, um diese Informationen abzurufen. Oder Sie haben eine separate Datenbanktabelle, in der Sie diese Referenzen verwenden. Nicht sicher, dass das hilft, gute Frage, ich werde darüber nachdenken. – Greg