Я читал документацию 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 {
}
Это определяет интерфейс, который используется как сервер (The Spring @RestController
превращает его в HTTP-сервер) и клиент (The Feign @FeignClient
настраивает его для использования клиентом HTTP). Реализации классов сервера и клиента можно использовать в отдельных проектах, но при этом использовать один и тот же интерфейс для обеспечения соответствия типов.
Тем не менее, под примером они поставили следующее предостережение:
Примечание. Как правило, не рекомендуется разделять интерфейс между сервером и клиентом. Он вводит тесную связь, а также фактически не работает с Spring MVC в его текущей форме (отображение параметров метода не наследуется).
ОК, так что это не очень хорошо интегрированы прямо сейчас ... но эта часть приходит после того, как предупреждение против обмена кода и введения соединения между сервером и клиентом, который по их мнению , является более важным. Почему они думают, что такой интерфейс - плохая идея?
Без этого вы потеряете возможность гарантировать, что сервер и клиент отправляют друг другу данные, которые они оба могут понять. Вы можете добавить поле к одному, но не к другому и обнаруживать несоответствие только до времени выполнения. На мой взгляд, это не введение связи, а просто выявление связи, которая уже существует. Является ли необходимость сделать серверы полностью независимыми больше, чем необходимость сообщать им, какие типы данных они будут получать?
источник
Ответы:
Причина, как указано в комментариях, заключается в том, что это приводит к тесной связи вашей клиентской платформы с вашей серверной платформой. Здесь это означает, что ваш клиент должен использовать язык / платформу, которую вы используете на сервере, чтобы понять ожидаемый контракт вашего сервера. Обратите внимание, что существует разница между совместным использованием одного и того же кода (артефакт определенного языка / платформы) и согласованием конкретного контракта.
Многие проекты вместо этого используют документацию для своих контрактов. Пример запросов и ответов в нейтральном формате (например, JSON) по стандартным протоколам (например, REST). (См. , Например, документы Stripe API ). Потому что нецелесообразно писать контракт на основе кода для каждой возможной клиентской платформы, которую вы можете использовать или разрешить. Третьи используют инструменты управления API для определения нейтральных контрактов .
Ваш пример добавления поля представляет собой отдельную проблему - пример того, почему это важно для версий API-контрактов. Пусть клиенты используют версию, для которой они предназначены. Неверно несовместимая новая версия API существует наряду со старой. Клиент для старой версии продолжает работать до тех пор, пока его команда не приступит к его обновлению или пока вы не удалите старую версию (после периода устаревания / миграции). Смотрите Параллельное изменение .
Следование (неявное указание в) предупреждению помогает клиенту и серверу развиваться способами и темпами, которые имеют смысл для каждого. Если вы можете разумно гарантировать, что ваш сервер и клиент всегда будут использовать один и тот же язык / платформу и развиваться в одном и том же темпе, то использование артефакта кода, специфичного для языка и платформы, так как ваш контракт, вероятно, будет в порядке. Тем не менее, это, вероятно, не является разумным ожиданием, особенно для проектов, нацеленных на Netflix OSS (что специально предназначено для масштабируемости и производительности облачных вычислений, со всей этой необходимой сложностью).
источник