Feign deklaratywny klient w microserwisach

W architekturze microserwisów jednym z ważniejszych aspektów jest komunikacja pomiędzy serwisami. Najprostszą i chyba najczęściej wykorzystywaną metodą jest łączenie się przy użyciu klienta http. Implementacji różnych klientów jest wiele. Ja dzisiaj opiszę Feign’a, klienta deklaratywnego, który pozwala nam zmniejszyć ilość pisanego kodu oraz znacznie ułatwia pracę.

Czym jest Feign ?

Feign jest deklaratywnym klientem http, co oznacza, że deklarujemy, co nasz klient ma robić, a nie to jak ma to robić (tak jak to jest w przypadku innych klientów http). Jeśli używamy spring boota to wystarczy nam jedna adnotacja do uruchomienia autokonfiguracji Feigna (@EnableFeignClients). Spring utworzy za nas takiego klienta i będziemy mogli go wstrzykiwać jak zwykłego beana.

Przykładowa deklaracja klienta Feign:

  1. Deklaracja klienta za pomocą adnotacji @FeignClient. Jako parametr podajemy url serwisu, do którego chcemy się połączyć.
  2. Deklaracja metody, która będzie łączyła się z odpowiednim zasobem.

Użycie takiego klienta jest bardzo proste i sprowadza się do wstrzyknięcia beana klienta oraz wywołania odpowiedniej metody, co upraszcza nam znacznie kod.

Prawda, że proste…

Inne klienty http

Apche commons HttpClient / Http Components

Gdy pierwszy raz używałem HttpClient wydał mi się całkiem prosty. Wtedy dopiero zaczynałem moją przygodę z javą i umiałem już używać oraz tworzyć klienty http w php używając np. fsockopen 😉 więc przesiadka była dosyć prosta.

Po krótkim czasie przyszła kolej na kolejną wersję HttpClient’a, który z wersją 4 zmienił swoją nazwę na Apache HttpComponents. Poza nazwą zmieniło się też api, które nawet teraz po wielu latach nie wydaje mi się zbyt przyjazne. HttpComponents daje za to bardzo duże możliwości. Można m.in. skonfigurować pulę wątków tak, by klient wykonywał zapytania równolegle w wielu wątkach. Może to być przydatne jeśli potrzebujesz napisać robota, który przemierza strony w poszukiwaniu różnych interesujących cię treści.

Jedną z pierwszych rzeczy jakie robiłem z klientami http było właśnie pisanie takich robotów. Oba te klienty mają jednak podobną wadę – konfiguracja ich bywa czasem kłopotliwa ze względu na mnogość opcji, które nam dają oraz mało intuicyjne api.

RestTemplate

Kolejnym podobnym klientem jest springowy restTemplate, jest on chyba najprostszy z tych wszystkich trzech. Jego wadą jest to (moim zdaniem), że metody api, które udostępnia i to jak się z nimi pracuje jest czasem mało wygodne. Nie wymaga natomiast dużo konfiguracji, a także potrafi skonwertować json’a na obiekty, co jest bardzo przydatne. Kolejną zaletą jest to, że istnieje także implementacja przeznaczona dla microserwisów z wbudowanym load balancerem i integracją z service discovery (wstrzykiwana adnotacją @LoadBalanced – spring cloud).

Poza wyżej wymienionymi jest jeszcze Jersey, do którego miałem kila podejść, ale jego api zupełnie mi nie odpowiada, więc postanowiłem więcej do niego nie wracać.

Proste rozwiązania są najlepsze

Niegdyś, kiedy potrzebowałem wygodnego klienta, zwykle robiłem własną implementację z fluent api – tak by żyło się lepiej – która przykrywała HttpComponents lub RestTemplate. Było to bardzo wygodne rozwiązanie i używało się go bardzo intuicyjnie, ale nadal było to rozwiązanie imperatywne, które z każdym użyciem generowało co najmniej kilka linijek kodu. Przy dużej ilości wywołań różnych endpointów http może stać się to dosyć uciążliwe.

Dlatego w projektach, w których nie mam zbyt dużo takich wywołań używam RestTemplate, głównie ze względu na jego prostotę, ale także dlatego, że jest to Springowy klient a springa używam do wszystkich projektów, więc dlaczego by nie używać RestTemplate.

Jak to jest zrobione ?

Tak naprawdę Feign nie jest klientem http tylko bardziej biblioteką, która używa klientów http takich jak Apache HttpComponents czy OkHttp. Generuje kod dla tych klientów i pozwala nam ich używać w bardzo wygodny sposób. Dzięki czemu cała logika związana z zapytaniami jest przed nami ukryta i nie miesza się z naszym kodem biznesowym.

Feign w microserwisach

Feign został stworzony przez netflixa i od początku przeznaczony był do pracy w środowisku microserwisów, potrafi więc korzystać z service discovery (może to być np. Eureka lub jakiś inny mechanizm discovery dostarczany przez np. chmurę np. discovery, które zapewnia Mezos). Feign używa Ribbona do łączenia z discovery i rozkładania ruchu na poszczególne instancje aplikacji (jest to Load Balancing server site).

Feign
Schemat połączeń Feigna w microverwisach

Instancje poszczególnych serwisów rejestrują się w serwis discovery, po czym Feign może pobrać listę zarejestrowanych serwisów. Zwykle serwisy rejestrują się pod nazwą (string) np. Service1, Service2.

W konfiguracji klienta (w adnotacji @FeignClient) zmieniamy jedynie url na name.

Oczywiście trzeba pamiętać o uruchomieniu autokonfiguracji klienta discovery w spring boot’cie, poprzez @EnableDiscoveryClient i możemy cieszyć się działającym połączeniem pomiędzy naszymi microserwisami.

Dlaczego klient deklaratywny jest lepszy?

Po zdefiniowaniu odpowiedniej konfiguracji jedyne co musimy wywołać w naszym kodzie to metoda, którą zdefiniowaliśmy i parametry wywołania:

nic więcej nie zaśmieca naszego kodu, nie musimy ręcznie tworzyć repozytorium, w którym będziemy trzymać implementację wywołań metod api.

Feign podobnie jak Spring Data minimalizuje szablonowy kod, który trzeba pisać przy pobieraniu podobnie ustrukturyzowanych danych, a przecież powszechnie wiadomo, że im mniej kodu tym lepiej… 🙂

Żródła:
https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-feign.html
https://github.com/OpenFeign/feign

Zapisz się na newsletter, żeby otrzymywać powiadomienia o nowych wpisach

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *