Inleiding tot Feign

1. Overzicht

In deze tutorial introduceren we Feign - een declaratieve HTTP-client ontwikkeld door Netflix.

Feign is gericht op het vereenvoudigen van HTTP API-clients. Simpel gezegd, de ontwikkelaar hoeft alleen een interface te declareren en te annoteren terwijl de daadwerkelijke implementatie tijdens runtime wordt geleverd.

2. Voorbeeld

In deze zelfstudie gebruiken we een voorbeeldboekhandeltoepassing die het REST API-eindpunt blootlegt.

We kunnen het project eenvoudig klonen en lokaal uitvoeren:

mvn install spring-boot: run

3. Installatie

Laten we eerst de benodigde afhankelijkheden toevoegen:

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

Naast de feign-core-afhankelijkheid (die ook wordt ingetrokken), zullen we een paar plug-ins gebruiken, vooral: feign-okhttp voor het intern gebruiken van de OkHttp-client van Square om verzoeken te doen, feign-gson voor het gebruik van Google's GSON als JSON-processor en veinzen- slf4j voor het gebruik van de Eenvoudige logging-gevel om verzoeken te loggen.

Om daadwerkelijk wat logboekuitvoer te krijgen, hebben we onze favoriete, door SLF4J ondersteunde loggerimplementatie op het klassenpad nodig.

Voordat we doorgaan met het maken van onze clientinterface, stellen we eerst een Boek model voor het bewaren van de gegevens:

openbare klasse Book {private String isbn; private String-auteur; private String-titel; private String synopsis; privé String-taal; // standaard constructor, getters en setters}

OPMERKING: Een JSON-processor heeft tenminste een "constructor zonder argumenten" nodig.

In feite is onze REST-provider een hypermedia-gestuurde API, dus we hebben bovendien een eenvoudige wrapper-klasse nodig:

openbare klasse BookResource {privéboekboek; // standaard constructor, getters en setters}

Opmerking: WijIk bewaar het BookResource eenvoudig omdat onze voorbeeld-Feign-client niet profiteert van hypermedia-functies!

4. Serverzijde

Om te begrijpen hoe u een Feign-client definieert, zullen we eerst enkele van de methoden en reacties bekijken die door onze REST-provider worden ondersteund.

Laten we het uitproberen met een eenvoudig curl-shell-commando om alle boeken weer te geven. We moeten onthouden om alle oproepen voor te voegen met / api, wat de servlet-context van de applicatie is:

curl // localhost: 8081 / api / books

Als gevolg hiervan krijgen we een complete boekenrepository die wordt weergegeven als JSON:

[{"book": {"isbn": "1447264533", "author": "Margaret Mitchell", "title": "Gone with the Wind", "synopsis": null, "language": 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 "}]}]

We kunnen ook individuele vragen stellen Boek bron, door het ISBN toe te voegen aan een ophaalverzoek:

curl // localhost: 8081 / api / books / 1447264533

5. Doe alsof je klant bent

Laten we tot slot onze Feign-client definiëren.

We gebruiken de @RequestLine annotatie om het HTTP-werkwoord en een padgedeelte als argument op te geven. De parameters worden gemodelleerd met behulp van de @Param annotatie:

openbare interface BookClient {@RequestLine ("GET / {isbn}") BookResource findByIsbn (@Param ("isbn") String isbn); @RequestLine ("GET") Lijst findAll (); @RequestLine ("POST") @Headers ("Content-Type: application / json") void create (Boekboek); }

OPMERKING: Feign-clients kunnen alleen worden gebruikt om op tekst gebaseerde HTTP-API's te gebruiken, wat betekent dat ze geen binaire gegevens kunnen verwerken, bijv. uploads of downloads van bestanden.

Dat is alles! Nu gebruiken we de Feign.builder () om onze interface-gebaseerde client te configureren. De daadwerkelijke implementatie wordt tijdens runtime geleverd:

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

Feign ondersteunt verschillende plug-ins zoals JSON / XML-encoders en decoders of een onderliggende HTTP-client voor het doen van de verzoeken.

6. Eenheidstest

Laten we drie testcases maken om onze klant te testen. Let op, we gebruiken statische invoer voor org.hamcrest.CoreMatchers. * en org.junit.Assert. *:

@Test openbare leegte gegevenBookClient_shouldRunSuccessfully () gooit uitzondering {List books = bookClient.findAll (). Stream () .map (BookResource :: getBook) .collect (Collectors.toList ()); assertTrue (books.size ()> 2); } @Test openbare leegte gegevenBookClient_shouldFindOneBook () gooit uitzondering {Boek book = bookClient.findByIsbn ("0151072558"). GetBook (); assertThat (book.getAuthor (), containsString ("Orwell")); } @Test openbare leegte gegevenBookClient_shouldPostBook () gooit uitzondering {String isbn = UUID.randomUUID (). ToString (); Boek boek = nieuw boek (isbn, "Me", "It's me!", Null, null); bookClient.create (boek); book = bookClient.findByIsbn (isbn) .getBook (); assertThat (book.getAuthor (), is ("Ik")); } 

7. Verder lezen

Als we een soort van terugval nodig hebben in het geval dat de service niet beschikbaar is, kunnen we HystrixFeign aan het klassenpad toevoegen en onze client bouwen met HystrixFeign.builder ().

Bekijk deze speciale tutorialserie voor meer informatie over Hystrix.

Bovendien, als we Spring Cloud Netflix Hystrix willen integreren met Feign, is er hier een speciaal artikel.

Bovendien is het ook mogelijk om client-side load-balancing en / of service discovery aan onze client toe te voegen.

We zouden dit kunnen bereiken door Ribbon aan ons klassenpad toe te voegen en de builder als volgt te gebruiken:

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

Om service te ontdekken, moeten we onze service opbouwen met Spring Cloud Netflix Eureka ingeschakeld. Integreer dan eenvoudig met Spring Cloud Netflix Feign. Als gevolg hiervan krijgen we gratis Ribbon load-balancing. Meer hierover vind je hier.

8. Conclusie

In dit artikel hebben we uitgelegd hoe je een declaratieve HTTP-client kunt bouwen met Feign om op tekst gebaseerde API's te gebruiken.

Zoals gewoonlijk zijn alle codevoorbeelden die in deze tutorial worden getoond, beschikbaar op GitHub.