Jak obsługiwać różne wersje API

15

Piszę interfejs API Rest i zastanawiam się, jak najlepiej obsługiwać różne wersje. Nie mam na myśli tego, jak zdefiniować identyfikator URI jako V2 lub V3, ale raczej jak ustrukturyzować kod, biorąc pod uwagę, że musiałby on:

  • Obsługa wielu wersji jednocześnie, np. Identyfikatory URI wersji V1, V2 i V3 muszą być jednocześnie aktywne. Chciałbym wycofać V1, gdy powie V4, aby ograniczyć obsługiwaną kwotę w dowolnym momencie.
  • Unikaj jak największego powielania kodu
  • Ułatw sobie dodawanie nieprzerwanych zmian do wersji, bez wpływu na inne wersje

Wydaje się, że istnieje kilka podejść, które można zastosować:

  • Użyj Git do sterowania wersjami, z gałęzią dla różnych wersji (a stare wersje zasadniczo nie wykonują żadnych nowych prac programistycznych). Oznaczałoby to brak duplikacji kodu, ponieważ tylko najnowsza wersja jest w kodzie, ale poprzednie wersje musiałyby współpracować z nową wersją bazy danych, dopóki nie zostaną wycofane.

  • Zduplikowany kod, dzięki czemu każda wersja jest obsługiwana w tej samej aplikacji i ma całkowicie oddzielną ścieżkę kodu, ale oznaczałoby to dużo duplikacji

  • Ponownie użyj dużej ilości kodu we wszystkich wersjach, ale utrudniłoby to utrzymanie, ponieważ zmiana jednej wersji może mieć wpływ na poprzednią wersję

Czy istnieje jakaś najlepsza praktyka, aby poradzić sobie z tym problemem, ponieważ wszystkie opcje wydają się mieć własne problemy?

Andy Davies
źródło
1
Jeśli określisz numer wersji w adresie URL (np. Myserver / api / 3.1.4 / user / get), możesz przekazać numer wersji do dowolnej wywoływanej funkcji, abyś mógł zlokalizować zachowanie specyficzne dla wersji bez współdzielenia zbyt dużej ilości kodu.
James McLeod

Odpowiedzi:

5

Zrób to:

Ponownie użyj dużej ilości kodu we wszystkich wersjach, ale utrudniłoby to utrzymanie, ponieważ zmiana jednej wersji może mieć wpływ na poprzednią wersję

ale nie psuj poprzednich wersji.

Powinieneś mieć testy sprawdzające, czy wszystkie obsługiwane wersje działają poprawnie. Jeśli nie masz tych testów, powinieneś je najpierw utworzyć, aby obejmował każdy zmieniany kod.

Kevin Cline
źródło
2

Kombinacja użycia gałęzi wydania GIT (lub rozwidlenia każdej wersji do osobnego repozytorium) do obsługi i utrzymania starych wersji API i ewentualnie posiadania kodu wielokrotnego użytku, który może być współdzielony jako zależność, podobnie jak biblioteka wspólna, jest najprawdopodobniej sposobem iść. Tak więc każda wersja interfejsu API byłaby artefaktem, który można wdrożyć oddzielnie. Umożliwia to elastyczność, dzięki czemu na przykład API V1 może zależeć od wspólnych V1, podczas gdy API V2, V3, V4 może zależeć od wspólnych V2. Byłoby to najłatwiejsze i najczystsze z punktu widzenia programowania, ponieważ twoja baza kodu nie mnoży się z każdą nową wersją, zamiast tego każda wersja jest izolowana w swoim własnym projekcie / bazie kodu i zajmuje się tylko sobą.

Innym powodem wdrażania osobnych artefaktów jest to, że mogą istnieć problemy przekrojowe, takie jak mechanizm bezpieczeństwa, lub frameworki / biblioteki, takie jak struktura wstrzykiwania zależności, które mogą ulec zmianie w nowszych wersjach interfejsu API i mogą utrudnić obsługę starszych interfejsów API, jeśli wszystkie działają w tej samej bazie kodu (i Classloader w czasie wykonywania, jeśli jest to Java).

Każde podejście, niezależnie od tego, czy jest to gałąź na wersję, czy monolityczna zduplikowana baza kodu, zawsze będzie wymagało zmiany wspólnego punktu integracji (takiego jak DB lub schemat rozproszonej pamięci podręcznej). Interfejsy API starszej wersji mogą wymagać pewnego rodzaju konserwacji do pracy z tymi zmianami lub wprowadzenia innych narzędzi (takich jak widoki bazy danych) w celu zapewnienia zgodności. Może to być nieunikniona trudność w zależności od charakteru twoich zmian.

PaulMooney
źródło
0

Nie wiem, jak różnią się wyniki od twoich wersji API, ale możesz mieć warstwę zgodności pośrodku, która może przełączać się między wersjami i wypełniać luki lub tłumaczyć dane.

To powiedziawszy - zwykle nigdy nie działa jeden na jeden - więc projekt przełącznika lub automatu stanów pomógł mi z tym problemem.

Zach Leighton
źródło