Uvod u Feign

1. Pregled

U ovom uputstvu predstavit ćemo Feign - deklarativni HTTP klijent koji je razvio Netflix.

Cilj programa Feign je pojednostaviti klijente HTTP API-ja. Jednostavno rečeno, programer treba samo deklarirati i označiti sučelje dok je stvarna implementacija predviđena za vrijeme izvođenja.

2. Primjer

Tijekom ovog vodiča koristit ćemo primjer aplikacije knjižare koja izlaže krajnju točku REST API-ja.

Projekt možemo lako klonirati i pokrenuti lokalno:

mvn instalirati spring-boot: trčanje

3. Postavljanje

Prvo, dodajmo potrebne ovisnosti:

 io.github.openfeign feign-okhttp 10.11 io.github.openfeign feign-gson 10.11 io.github.openfeign feign-slf4j 10.11 

Osim ovisnosti o jezgri o jezgri (koja se također uvlači), koristit ćemo nekoliko dodataka, posebno: feign-okhttp za interno korištenje kvadrata OkHttp klijenta za izradu zahtjeva, feign-gson za upotrebu Googleovog GSON-a kao JSON procesora i feign- slf4j za korištenje Jednostavna fasada sječe za evidentiranje zahtjeva.

Da bismo zapravo dobili neke izlaze iz dnevnika, trebat će nam naša omiljena, podržana SLF4J implementacija zapisnika na putu predavanja.

Prije nego što nastavimo s izradom klijentskog sučelja, prvo ćemo postaviti a Knjiga model za čuvanje podataka:

javna klasa Book {private String isbn; privatni autor niza; privatni naslov niza; privatni sinoptički niz; privatni jezik gudača; // standardni konstruktor, getteri i postavljači}

BILJEŠKA: JSON procesor treba barem "konstruktor bez argumenata".

Zapravo je naš REST davatelj API koji pokreće hipermedija, pa će nam dodatno trebati jednostavna klasa omota:

public class BookResource {privatna knjiga knjiga; // standardni konstruktor, getteri i postavljači}

Bilješka: MiZadržat ću BookResource jednostavno jer naš uzorak klijenta Feign nema koristi od hipermedijskih značajki!

4. Na strani poslužitelja

Da bismo razumjeli kako definirati klijenta Feign, prvo ćemo razmotriti neke metode i odgovore koje podržava naš REST pružatelj.

Isprobajmo je s jednostavnom naredbom curl shell da bismo popisali sve knjige. Moramo se sjetiti da pred sve pozive dodamo oznaku / api, što je kontekst servleta aplikacije:

uvojak // localhost: 8081 / api / books

Kao rezultat, dobit ćemo kompletno spremište knjiga predstavljeno kao JSON:

[{"book": {"isbn": "1447264533", "author": "Margaret Mitchell", "title": "Gone with the Wind", "sinopsis": null, "language": null}, "linkovi ": [{" rel ":" self "," href ":" // localhost: 8081 / api / books / 1447264533 "}]}, ... {" book ": {" isbn ":" 0451524934 ", "author": "George Orwell", "title": "1984", "synopsis": null, "language": null}, "links": [{"rel": "self", "href": "/ / localhost: 8081 / api / books / 0451524934 "}]}]

Možemo također pitati pojedinca Knjiga resursa, dodavanjem ISBN-a zahtjevu za dobivanje:

uvojak // localhost: 8081 / api / books / 1447264533

5. Klijent koji glumi

Na kraju, definirajmo našeg klijenta Feign.

Koristit ćemo @RequestLine napomena za specificiranje HTTP glagola i dijela puta kao argumenta. Parametri će se modelirati pomoću @Param napomena:

javno sučelje BookClient {@RequestLine ("GET / {isbn}") BookResource findByIsbn (@Param ("isbn") String isbn); @RequestLine ("GET") Popis findAll (); @RequestLine ("POST") @Headers ("Content-Type: application / json") void create (Knjiga knjiga); }

BILJEŠKA: Klijenti koji glume mogu se koristiti za konzumiranje samo tekstualnih HTTP API-ja, što znači da ne mogu rukovati binarnim podacima, npr. prijenos datoteka ili preuzimanja.

To je sve! Sada ćemo koristiti Feign.builder () za konfiguriranje našeg klijenta temeljenog na sučelju. Stvarna implementacija bit će osigurana za vrijeme izvođenja:

BookClient bookClient = Feign.builder () .client (novi OkHttpClient ()) .encoder (novi GsonEncoder ()) .decoder (novi GsonDecoder ()) .logger (novi Slf4jLogger (BookClient.class)) .logLevel (Logger.Level (Logger.Level (Logger.Level)). FULL) .target (BookClient.class, "// localhost: 8081 / api / books");

Feign podržava razne dodatke poput JSON / XML kodera i dekodera ili temeljni HTTP klijent za izradu zahtjeva.

6. Jedinstveni test

Stvorimo tri testna slučaja kako bismo testirali našeg klijenta. Napomena, mi koristimo statički uvoz org.hamcrest.CoreMatchers. * i org.junit.Assert. *:

@Test public void givenBookClient_shouldRunSuccessfully () baca izuzetak {Popis knjiga = bookClient.findAll (). Stream () .map (BookResource :: getBook) .collect (Collectors.toList ()); assertTrue (books.size ()> 2); } @Test public void givenBookClient_shouldFindOneBook () baca izuzetak {Book book = bookClient.findByIsbn ("0151072558"). GetBook (); assertThat (book.getAuthor (), containsString ("Orwell")); } @Test public void givenBookClient_shouldPostBook () baca iznimku {String isbn = UUID.randomUUID (). ToString (); Knjiga knjiga = nova Knjiga (isbn, "Ja", "To sam ja!", Null, null); bookClient.create (knjiga); book = bookClient.findByIsbn (isbn) .getBook (); assertThat (book.getAuthor (), je ("Ja")); } 

7. Daljnje čitanje

Ako trebamo neku rezervnu mogućnost u slučaju nedostupnosti usluge, mogli bismo dodati HystrixFeign na put predavanja i izgraditi našeg klijenta s HystrixFeign.builder ().

Pogledajte ovu posvećenu seriju vodiča da biste saznali više o Hystrixu.

Osim toga, ako želimo integrirati Spring Cloud Netflix Hystrix s Feign-om, ovdje je posvećen članak.

Štoviše, klijentu je također moguće dodati uravnoteženje opterećenja na strani klijenta i / ili otkrivanje usluge.

To bismo mogli postići dodavanjem vrpce u našu put predavanja i korištenjem graditelja na takav način:

BookClient bookClient = Feign.builder () .client (RibbonClient.create ()) .target (BookClient.class, "// localhost: 8081 / api / books");

Za otkrivanje usluge moramo izgraditi našu uslugu s omogućenom Spring Cloud Netflix Eurekom. Zatim se jednostavno integrirajte s Spring Cloud Netflix Feign. Kao rezultat, dobivamo uravnoteženje opterećenja vrpce besplatno. Više o tome možete pronaći ovdje.

8. Zaključak

U ovom smo članku objasnili kako izraditi deklarativni HTTP klijent koristeći Feign za konzumiranje API-ja temeljenih na tekstu.

Kao i obično, svi uzorci koda prikazani u ovom vodiču dostupni su na GitHubu.