Spring Cloud Netflix: Feign по-русски
Привет.
Я хочу продолжить серию из предыдущих статей по Netflix, а именно поговорить про Feign Client.
На русском языке очень мало информации по стеку Netflix.
И правильно, потому что надо читать официальную документацию, там вы найдете больше всего. Но я все же решил рассказать “своими словами” чтобы сложилась более ясная картина при изучении данного стека для тех, кто предпочитает русскоязычную литературу.
Планирую обновлять статьи по мере изучения нового материала. Если у вас есть предложения на этот счет, буду рад выслушать.
Другие реализации Feign Client я рассмотрел в другой статье:
Feign — простой и гибкий http-клиент, который нативно интегрирован с Ribbon (О нем в другой статье).
Feign использует интерфейсы аннотированные @FeignClient чтобы генерировать API запросы и мапить ответ на Java классы.
Он шлет http запросы другим сервисам.
Его особенность в том, что нам не нужно знать где и на каком порту находится какой-то сервис.
Мы просто говорим Feign клиенту, иди к “Джон Уику” и получи у него всех пользователей. Далее Feign обращается к Eureka Server и спрашивает где находится “Джон Уик”.
Если “Джон Уик” регистрировался в Eureka Server, то Eureka будет всё знать о “Джон Уик” (где он находится, на каком порту, его URL и т.д.)
Вам нужно только описать, как получить доступ к удаленной службе API, указав такие детали, как URL, тело запроса и ответа, принятые заголовки и т. д. Клиент Feign позаботится о деталях реализации.
Netflix предоставляет Feign в качестве абстракции для вызовов на основе REST, благодаря которым микросервисы могут связываться друг с другом, но разработчикам не нужно беспокоиться о внутренних деталях REST.
Нужно указать аннотацию @EnableFeignClients над основным классом
@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
public class FeignClientApplication {
public static void main(String[] args) {
SpringApplication.run(FeignClientApplication.class, args);
}
}
На интерфейс ставим аннотацию @FeignClient(name = “Джон Уик”) и указываем имя того сервиса, который нам нужен (в пояснении я описывал сервис под названием “Джон Уик”). В том сервисе будет выполняться некая логика по работе с базой и настройки коннекта к базе, или получение всех пользователей и т.д.
Feign — это первый шаг в реализации архитектуры микросервиса при помощи инструментов Netflix.
В реальности слабо связанных сервисов очень важно чтобы общение между ними было легковесным и простым для отладки.
Поэтому для этой цели зачастую используют REST, хотя для некоторых случаев это может быть не лучшим выбором.
Еще раз: для упрощения связи по REST мы и используем Feign: при помощи него мы будем поглощать сообщения от других сервисов и автоматически превращать их в Java объекты.
Рассмотрим небольшой и в то же время очень простой пример.
У нас есть сервис А и сервис B, которые оба зарегистрированы в Eureka. Мы хотим из сервиса А вызвать сервис B и получить какие-то данные.
Сервис B имеет следующий контроллер:
@RestController
@RequestMapping(“/users/{id}/statistic”)
public class StatisticsController {
@Autowired
StatisticsService statisticsService;
public List<UserStatisticModel> getStatistic(@PathVariable String id) {
List<UserStatisticModel> statisticsList = statisticsService.getAlbums(id);
return statisticsList;
}
}
и модель:
public class UserStatisticModel {
private Long id;
private String userId;
private String username;
private String title;}
Используем Lombok чтобы избавиться от ненужного кода геттеров и сеттеров.
Чтобы из сервиса А вызвать сервис B мы создадим в сервисе А feign client.
В аннотации @FeignClient мы указываем имя того сервиса, который хотим вызвать (сервис B).
@FeignClient(name = “B”)
public interface ServiceFeignClient {
@GetMapping(“/users/${id}/statistic”)
public List<UserStatisticModel> getStatistic(@PathVariable String id);
}
Аннотация @GetMapping содержит путь, который отображается на тот же самый путь в аннотации @RequestMapping в микросервисе B и указывает, что это будет GET запрос.
Метод должен иметь такую-же сигнатуру что и метод в сервисе B. Это важно!
Модель:
public class UserStatisticModel {
private Long id;
private String userId;
private String username;
private String title;}
Теперь чтобы создать экземпляр клиента Feign, вам нужно будет автоматически подключить интерфейс клиента feign к вашему классу, в котором вызывается логика.
@Service
public class UsersServiceImpl implements UsersService {@Autowired
ServiceFeignClient serviceFeignClient;….
List<AlbumResponseModel> albumsList = serviceFeignClient.getStatistic(userId);
….
}
Теперь когда мы будем дергать URL “/users/${id}/statistic” из ServiceFeignClient сервиса А, он посмотрит на аннотацию @FeignClient(name = “B”) и увидит, что там указан сервис B, пойдет к нему и по этому же URL в StatisticsController вызовет метод getStatistic.
Все очень просто.
Также хочу добавить, если вам нужно использовать внешнюю веб-службу, которая не является частью вашей архитектуры микросервисов и не зарегистрирована в вашей службе Eureka, то используйте URL в качестве параметра аннотации @FeignClient.
@FeignClient(name = “B”, url = “http://lalalala")
public interface ServiceFeignClient {
@GetMapping(“/users/${id}/statistic”)
public List getStatistic(@PathVariable String id);
}
Если вы нашли неточности в описании данной статьи, вы можете написать мне на email и я с радостью вам отвечу.
Kirill Sereda
email: kirill.serada@gmail.com
skype: kirill-sereda
linkedin: www.linkedin.com/in/ksereda