Załóżmy, że masz duży projekt obsługiwany przez bazę API. Projekt udostępnia także publiczny interfejs API, z którego mogą korzystać użytkownicy końcowi (ish).
Czasami musisz wprowadzić zmiany w bazie API obsługującej Twój projekt. Na przykład musisz dodać funkcję, która wymaga zmiany interfejsu API, nowej metody lub wymaga zmiany jednego z obiektów lub formatu jednego z tych obiektów, przekazanych do lub z interfejsu API.
Zakładając, że używasz również tych obiektów w publicznym interfejsie API, obiekty publiczne zmienią się również za każdym razem, gdy to zrobisz, co jest niepożądane, ponieważ Twoi klienci mogą polegać na obiektach API, które pozostają identyczne, aby działał ich kod analizujący. (kaszel klientów WSDL C ++ ...)
Tak więc jednym potencjalnym rozwiązaniem jest wersja API. Ale kiedy mówimy „wersja” interfejsu API, brzmi to tak, że musi to również oznaczać wersję obiektów API, a także zapewnienie duplikatów wywołań metod dla każdej zmienionej sygnatury metody. Więc miałbym wtedy zwykły stary obiekt clr dla każdej wersji mojego interfejsu API, co znów wydaje się niepożądane. I nawet jeśli to zrobię, na pewno nie będę budował każdego obiektu od zera, ponieważ skończyłoby się to ogromną ilością powielonego kodu. Raczej API może rozszerzyć prywatne obiekty, których używamy do naszego podstawowego API, ale potem napotykamy ten sam problem, ponieważ dodane właściwości byłyby również dostępne w publicznym API, gdy nie powinny.
Jaki jest zatem rozsądek, który zwykle stosuje się w tej sytuacji? Wiem, że wiele usług publicznych, takich jak Git dla Windows, utrzymuje wersjonowany interfejs API, ale mam problem z wyobrażeniem sobie architektury, która to obsługuje bez ogromnej ilości zduplikowanego kodu obejmującego różne metody wersjonowane i obiekty wejścia / wyjścia.
Zdaję sobie sprawę, że procesy takie jak semantyczna wersja wersjonowania próbują wprowadzić rozsądek, kiedy powinny wystąpić przerwy w publicznym API. Problem polega na tym, że wydaje się, że wiele lub większość zmian wymaga zepsucia publicznego interfejsu API, jeśli obiekty nie są bardziej oddzielone, ale nie widzę dobrego sposobu na zrobienie tego bez powielania kodu.
I don't see a good way to do that without duplicating code
- Twój nowy interfejs API zawsze może wywoływać metody w starym interfejsie API lub odwrotnie.