Introduktion til Feign

1. Oversigt

I denne vejledning introducerer vi Feign - en deklarativ HTTP-klient udviklet af Netflix.

Feign sigter mod at forenkle HTTP API-klienter. Kort sagt, udvikleren behøver kun at erklære og kommentere en grænseflade, mens den faktiske implementering er klargjort under kørsel.

2. Eksempel

I hele denne tutorial bruger vi et eksempel på en boghandelapplikation, der afslører REST API-slutpunktet.

Vi kan nemt klone projektet og køre det lokalt:

mvn installer spring-boot: run

3. Opsætning

Lad os først tilføje de nødvendige afhængigheder:

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

Udover feign-core afhængighed (som også trækkes ind) bruger vi et par plugins, især: feign-okhttp til intern brug af Square's OkHttp-klient til at stille anmodninger, feign-gson til brug af Googles GSON som JSON-processor og feign- slf4j til brug af Enkel logning facade for at logge anmodninger.

For faktisk at få noget logoutput skal vi bruge vores foretrukne, SLF4J-understøttede loggerimplementering på klassestien.

Før vi fortsætter med at oprette vores klientgrænseflade, opretter vi først en Bestil model til opbevaring af data:

public class Book {private String isbn; privat strengforfatter; privat streng titel; privat String synopsis; private String sprog; // standard konstruktør, getters og setter}

BEMÆRK: Mindst en "ingen argumenter konstruktør" er nødvendig af en JSON-processor.

Faktisk er vores REST-udbyder en hypermediedrevet API, så vi har desuden brug for en simpel indpakningsklasse:

offentlig klasse BookResource {privat bogbog; // standard konstruktør, getters og setter}

Bemærk: ViJeg beholder BookResource simpelt, fordi vores eksempler på Feign-klient ikke drager fordel af hypermedia-funktioner!

4. Serverside

For at forstå, hvordan man definerer en Feign-klient, ser vi først på nogle af de metoder og svar, der understøttes af vores REST-udbyder.

Lad os prøve det med en simpel curl shell-kommando for at liste alle bøgerne. Vi er nødt til at huske at sætte alle opkald foran / api, som er applikationens servlet-kontekst:

krølle // localhost: 8081 / api / books

Som et resultat får vi et komplet bogopbevaring repræsenteret som JSON:

[{"book": {"isbn": "1447264533", "author": "Margaret Mitchell", "title": "Borte med vinden", "synopsis": null, "sprog": null}, "links ": [{" 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 "}]}]

Vi kan også spørge individuelt Bestil ressource ved at tilføje ISBN til en get-anmodning:

krølle // localhost: 8081 / api / books / 1447264533

5. Feign-klient

Lad os endelig definere vores Feign-klient.

Vi bruger @RequestLine kommentar for at specificere HTTP-verbet og en stigdel som et argument. Parametrene modelleres ved hjælp af @Param kommentar:

offentlig grænseflade BookClient {@RequestLine ("GET / {isbn}") BookResource findByIsbn (@Param ("isbn") Streng isbn); @RequestLine ("GET") Liste findAll (); @RequestLine ("POST") @Headers ("Content-Type: application / json") ugyldig oprettelse (bogbog); }

BEMÆRK: Feign-klienter kan kun bruges til at forbruge tekstbaserede HTTP API'er, hvilket betyder, at de ikke kan håndtere binære data, f.eks. fil uploads eller downloads.

Det er alt! Nu bruger vi Feign.builder () for at konfigurere vores interface-baserede klient. Den faktiske implementering tilvejebringes ved kørsel:

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

Feign understøtter forskellige plugins som JSON / XML-kodere og dekodere eller en underliggende HTTP-klient til at stille anmodningerne.

6. Enhedstest

Lad os oprette tre testsager for at teste vores klient. Bemærk, vi bruger statisk import til org.hamcrest.CoreMatchers. * og org.junit.Assert. *:

@Test offentligt ugyldigt givetBookClient_shouldRunSuccessfully () kaster undtagelse {List books = bookClient.findAll (). Stream () .map (BookResource :: getBook) .collect (Collectors.toList ()); assertTrue (books.size ()> 2); } @Test offentlig ugyldighed givetBookClient_shouldFindOneBook () kaster undtagelse {Book book = bookClient.findByIsbn ("0151072558"). GetBook (); assertThat (book.getAuthor (), indeholderString ("Orwell")); } @Test offentlig ugyldighed givetBookClient_shouldPostBook () kaster undtagelse {String isbn = UUID.randomUUID (). ToString (); Bogbog = ny bog (isbn, "Mig", "Det er mig!", Null, null); bookClient.create (bog); bog = bookClient.findByIsbn (isbn) .getBook (); assertThat (book.getAuthor (), er ("Mig")); } 

7. Yderligere læsning

Hvis vi har brug for en form for tilbageførsel i tilfælde af, at tjenesten ikke er tilgængelig, kan vi tilføje HystrixFeign til klassestien og bygge vores klient med HystrixFeign.builder ().

Se denne dedikerede tutorial-serie for at lære mere om Hystrix.

Derudover, hvis vi gerne vil integrere Spring Cloud Netflix Hystrix med Feign, er der en dedikeret artikel herover.

Desuden er det også muligt at tilføje belastningsbalancering på klientsiden og / eller opdagelse af tjenester til vores klient.

Vi kunne opnå dette ved at tilføje bånd til vores klassesti og bruge bygherren sådan:

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

For at finde service er vi nødt til at opbygge vores service med Spring Cloud Netflix Eureka aktiveret. Integrer derefter blot med Spring Cloud Netflix Feign. Som et resultat får vi Ribbon load-balancing gratis. Mere om dette kan findes her.

8. Konklusion

I denne artikel har vi forklaret, hvordan man bygger en deklarativ HTTP-klient ved hjælp af Feign til at forbruge tekstbaserede API'er.

Som normalt er alle kodeeksempler vist i denne vejledning tilgængelige på GitHub.