Czytałem dokumentację Spring Cloud Netflix, gdy dowiedziałem się o sposobie udostępniania interfejsu między serwerem HTTP a jego klientem. Korzystają z tego przykładu w przypadku mikrousług, chociaż nie ma powodu, dla którego nie może ono obejmować ogólnej komunikacji HTTP:
// The shared interface, in a common library
public interface UserService {
@RequestMapping(method = GET, value = "/users/{id}")
User getUser(@PathVariable long id);
}
// The controller, on the server
@RestController
public class UserResource implements UserService {
}
// The same interface used for the client
@FeignClient("users")
public interface UserClient extends UserService {
}
Definiuje to interfejs, który jest używany zarówno jako serwer (Spring @RestController
zamienia go w serwer HTTP), jak i klient (Feign @FeignClient
konfiguruje go do użytku klienta HTTP). Implementacje klasy serwer i klient mogą być używane w oddzielnych projektach, ale nadal używają tego samego interfejsu, aby zapewnić zgodność typów.
Jednak pod tym przykładem podają następujące zastrzeżenie:
Uwaga: Zasadniczo nie zaleca się udostępniania interfejsu między serwerem a klientem. Wprowadza ścisłe sprzężenie, a także faktycznie nie działa z Spring MVC w obecnej formie (mapowanie parametrów metody nie jest dziedziczone).
OK, więc nie jest teraz dobrze zintegrowany ... ale ta część pojawia się po ostrzeżeniu przed udostępnianiem kodu i wprowadzeniem sprzężenia między serwerem a klientem, co według nich jest ważniejsze. Dlaczego uważają, że dzielenie interfejsu w ten sposób jest kiepskim pomysłem?
Bez tego tracisz możliwość zagwarantowania, że serwer i klient wysyłają sobie nawzajem dane, które mogą zrozumieć. Możesz dodać pole do jednego, ale nie do drugiego, i wykryć niezgodność tylko do czasu wykonania. Moim zdaniem nie wprowadza sprzężenia, ale jedynie ujawnia sprzężenie, które już istnieje. Czy potrzeba, aby serwery były całkowicie niezależne, jest większa niż potrzeba poinformowania ich, jakie typy danych otrzymają?