Я читав документацію Spring Cloud Netflix, коли дізнався про спосіб спільного використання інтерфейсу між HTTP-сервером та його клієнтом. Вони використовують цей приклад для мікросервісів, хоча немає причини, чому він не може поширюватися на загальний 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 {
}
Це визначає інтерфейс, який використовується як сервер (весна @RestController
перетворює його на сервер HTTP), так і клієнт (Feign @FeignClient
встановлює його для використання HTTP-клієнта). Реалізації серверного та клієнтського класів можуть використовуватися в окремих проектах, але все ж використовувати один і той же інтерфейс для забезпечення відповідності типів.
Однак під прикладом вони містять наступне застереження:
Примітка. Зазвичай не доцільно ділитися інтерфейсом між сервером і клієнтом. Він вводить жорстке з'єднання, а також фактично не працює з Spring MVC в його поточному вигляді (відображення параметрів методу не успадковується).
Гаразд, тому це не дуже інтегровано зараз ... але ця частина з’являється після попередження про код спільного використання та введення зв'язку між сервером і клієнтом, що, на їхню думку, є більш важливим. Чому вони вважають, що подібна інтерфейс таким чином погана ідея?
Без цього ви втрачаєте можливість гарантувати, що сервер і клієнт надсилають один одному дані, які вони можуть обидва зрозуміти. Ви можете додати поле до одного, але не до іншого, і виявити невідповідність лише до часу виконання. На мій погляд, це не введення з’єднання, а просто виявлення зв'язку, яка вже існує. Чи є необхідність зробити сервери абсолютно незалежними більшою, ніж необхідність повідомляти їм, які типи даних вони отримуватимуть?