2013-03-25 20 views
9

Zanim uznasz to za duplikat, poświęć chwilę. Kiedy badam Web Api w kwestii wersji, wszystko jest zaniepokojone wersjonowanymi kontrolerami i najlepszymi praktykami związanymi z określaniem wersji w url vs. nagłówki.Rozwiązanie do porównywania odpowiedzi Web Api?

Próbuję dowiedzieć się, co jest najlepszym sposobem na wyjście wersji odpowiedzi, więc nie złamać Wersja 1 klientom, kiedy wyjdzie z wersji 2.

Powiedzmy mam ciągła zmiana DAL dla pakietu witryn, który zasila stronę internetową i inne usługi. Pracuję nad nowym projektem Web Api, który powinien zawierać odpowiedzi zgodne ze schematami wersji.

Moje pytanie, jakie są sprawdzone rozwiązania/najlepsze praktyki dotyczące wykonania wersjonowanie w projektach WWW interfejsu API przeszłość wersjami sterowników i przed un-wersjonowanych dal?

Wpadłem na rozwiązanie, które obejmuje dodatkową warstwę wersji repozytoriów i dodatkową warstwę modeli wersji, więc wersje kontrolerów używają wersjonowanych repozytoriów, które używają wersji modeli. I skonfigurowałem Automappera do mapowania pomiędzy niefizycznymi modelami domen (z DAL) a wersjonowanymi modelami. Ale wadą tej konfiguracji jest to, że muszę zaktualizować wszystkie mapy dla każdej nowej wersji; narastający problem wykładniczy.

Musi istnieć lepszy sposób. Dzięki!

+0

https://github.com/Sebazzz/SDammann.WebApi.Versioning – adt

+0

To świetne rozwiązanie dla kontrolerów wersji, ale jak już powiedziałem, nie szukam tego. – Levitikon

+0

Jedyne, co mogłem wymyślić; byłoby stworzyć samowystarczalny model, który przechowuje te dane. Następnie użyj kontrolera, aby pobrać te informacje. Lub, aby mieć oddzielną tabelę bazy danych, w której można wykorzystać te odniesienia. Nie jestem pewien, czy to pomoże, dobre pytanie, nad czym się zastanowię. – Greg

Odpowiedz

1

Z mojego doświadczenia wynika, najczystsze (ale nie najłatwiejsze) rozwiązanie okazało przychodzi w 5 części:

  1. mającą autorytatywny model danych i tylny koniec, który jest zawsze na bieżąco : DAL/Database/Services.
  2. Posiadanie danych specyficznych dla wersji, które są zrozumiałe dla systemu: wiele modeli danych.
  3. Zapewnienie, że zmiany pomiędzy wersją są identyfikowane i śledzone prawidłowo i że zmiany są odwracalne. Reguły muszą być jawnie zdefiniowane, aby sobie z tym poradzić (co może być trudniejsze): Konwertery.
  4. Making klient wyraźnie powiedzieć, która wersja używają: Query Strings/nagłówków.
  5. Mając autorytatywny logiki biznesowej, która jest zawsze aktualne, ale wie, jak poruszać się pomiędzy inną wersję danych - kompatybilne wstecznie: Sterowniki.

Dane modelu mamy jest Dostawca np.

(1) Back End (tj. DAL/baza danych) znajduje się na poziomie V5. Logika biznesowa (tj. Usługi) jest również na V5.

(2) Jednak musimy służyć klienta dostawca V1, V2, V3, V4 i aktualne klienta na V5 wszystkich w tym samym czasie. Zróbmy V1 do V5 naszego modelu danych: SupplierV1, SupplierV2 ... (można używać nazw, lub innych sposobów, aby je różnicują)

(3) trzeba zdefiniować konwertery i zarządzać nimi. Muszą one obsługiwać zarówno kompatybilność w przód, jak i w tył między wersjami modeli danych. Można to zrobić za pomocą wzoru strategii, lambdas, menedżera z konwerterami DI itp.Będziesz musiał obsłużyć: V1-> V2-> V3-> V4-> V5, ale także V5-> V4-> V3-> V2-> V1.

Zasady dotyczące przetworników są najtrudniejsze. Czasami jest to łatwe - Wartości domyślne dla nowych pól. Innym razem musisz uruchomić jakąś logikę biznesową. Kiedyś musisz konwertować/scalać istniejące dane; musisz się upewnić, że jest odwracalny! Na przykład, jeśli wartości są w mieszanym przypadku w V1 i konwertujesz je na wielkie litery w V2 ... nie będziesz w stanie przywrócić go do wersji V1, ponieważ nie masz pojęcia, które znaki były wielkie i małe. Możesz obsłużyć to na dwa sposoby:

  • Zachowaj go w dużych literach dla V1. Wszakże wymaga tego tylko V2, V1 prawdopodobnie działa ze wszystkimi dużymi przypadkami (oczywiście nie działałoby na klucze).
  • Zachowaj starą wartość w polu w V2. Na przykład, jeśli zdecydujesz się na duże litery stanu pola, możesz zachować wartość oryginalną, która jest mieszana i skopiować ją do stanu po powrocie do wersji V1.

Jak widać, trzeba myśleć o tych trudnych i często nietrywialnych.

(4) Następnie w kontrolerach, trzeba wiedzieć, która wersja klient współpracuje z zrobić konwersję i wyjść regulatora, gdy są potrzebne. W tym celu można użyć ciągi zapytań, nagłówki (X-API-Version lub Zebrane na przykład, ale uważaj niektóre host/proxy paski niektóre z nich), parametr pisać itp

(5) W końcu, kiedy kontroler odbiera model danych, musisz sprawdzić, którą wersję wysłał klient (powiedzmy V2) i zaktualizować go do najnowszej wersji dla zaplecza (V5). Następnie użyj go poprawnie, a następnie, jeśli chcesz wysłać dane z powrotem, musisz obniżyć go do wersji klienta (V2). Aby to zrobić, można zrobić zwyczaj wiązania, działania niestandardowe żądanie, niestandardowe wyniki akcji, itp na przykład (proszę zautomatyzowania tego):

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); 
} 

To bardzo surowy sposób, aby pokazać wam ten pomysł. To jest coś, co zrobiliśmy w jednym z naszych systemów. Możesz mieć menedżerów, którzy wykrywają typy i wersje i sami zajmują się konwersją, możesz dynamicznie ładować zespół/konwertery za pomocą wtrysku zależności, możesz zautomatyzować większość konwersji w niestandardowych powiązaniach/żądaniach akcji i tak dalej.

Uwaga: Jest też część (6) może trzeba rozważyć. Aby faktycznie zaktualizować dane klienta w bazie danych do wersji V5, można to zrobić podczas migracji do wersji V5 (migracja wsadowa danych), LUB, zrób to w czasie wykonywania. Kiedy otrzymasz SupplierV1, ładujesz go z bazy danych (nadal dane V1), dokonaj aktualizacji do wersji V5 i zapisz zaktualizowane dane, wszystkie w konwerterze. Oznacza to, że masz teraz w locie migrację twojego backendu. Oczywiście nie jest to tak proste, jak się wydaje, ponieważ musisz obsługiwać obie wersje w tej samej bazie danych, ale może Ci się to udać w zależności od rodzaju wprowadzonych zmian lub danych.