Introduction à Feign

1. Vue d'ensemble

Dans ce tutoriel, nous présenterons Feign - un client HTTP déclaratif développé par Netflix.

Feign vise à simplifier les clients API HTTP. En termes simples, le développeur n'a qu'à déclarer et annoter une interface pendant que l'implémentation réelle est provisionnée au moment de l'exécution.

2. Exemple

Tout au long de ce didacticiel, nous utiliserons un exemple d'application de librairie qui expose le point de terminaison de l'API REST.

Nous pouvons facilement cloner le projet et l'exécuter localement:

mvn install spring-boot:run

3. Configuration

Tout d'abord, ajoutons les dépendances nécessaires:

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

Outre la dépendance feign-core (qui est également intégrée), nous utiliserons quelques plugins, en particulier: feign-okhttp pour utiliser en interne le client OkHttp de Square pour faire des requêtes, feign-gson pour utiliser GSON de Google comme processeur JSON et feindre- slf4j pour utiliser la façade de journalisation simple pour consigner les demandes.

Pour obtenir une sortie de journal, nous aurons besoin de notre implémentation de journalisation préférée, prise en charge par SLF4J sur le chemin de classe.

Avant de procéder à la création de notre interface client, nous allons d'abord configurer un modèle Book pour contenir les données:

public class Book { private String isbn; private String author; private String title; private String synopsis; private String language; // standard constructor, getters and setters }

REMARQUE: au moins un «constructeur sans arguments» est requis par un processeur JSON.

En fait, notre fournisseur REST est une API basée sur l'hypermédia , nous aurons donc également besoin d'une classe wrapper simple:

public class BookResource { private Book book; // standard constructor, getters and setters }

Note: Nous ' allons garder la BookResource simple parce que notre échantillon client Feindre ne bénéficie pas de fonctionnalités hypermédias!

4. Côté serveur

Pour comprendre comment définir un client Feign, nous allons d'abord examiner certaines des méthodes et réponses prises en charge par notre fournisseur REST.

Essayons-le avec une simple commande curl shell pour lister tous les livres. Nous devons nous rappeler de préfixer tous les appels avec / api , qui est le contexte de servlet de l'application:

curl //localhost:8081/api/books

En conséquence, nous obtiendrons un référentiel de livres complet représenté sous forme de 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" } ] } ]

Nous pouvons également interroger une ressource de livre individuelle , en ajoutant l'ISBN à une demande d'obtention:

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

5. Feignez le client

Enfin, définissons notre client Feign.

Nous utiliserons l' annotation @RequestLine pour spécifier le verbe HTTP et une partie de chemin comme argument. Les paramètres seront modélisés à l'aide de l' annotation @Param :

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

REMARQUE: les clients Feign peuvent être utilisés pour consommer uniquement des API HTTP textuelles, ce qui signifie qu'ils ne peuvent pas gérer les données binaires, par exemple les téléchargements de fichiers ou les téléchargements.

C'est tout! Nous allons maintenant utiliser Feign.builder () pour configurer notre client basé sur l'interface. L'implémentation réelle sera provisionnée au moment de l'exécution:

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

Feign prend en charge divers plugins tels que les encodeurs et décodeurs JSON / XML ou un client HTTP sous-jacent pour effectuer les requêtes.

6. Test unitaire

Créons trois cas de test pour tester notre client. Notez que nous utilisons des importations statiques pour org.hamcrest.CoreMatchers. * Et org.junit.Assert. * :

@Test public void givenBookClient_shouldRunSuccessfully() throws Exception { List books = bookClient.findAll().stream() .map(BookResource::getBook) .collect(Collectors.toList()); assertTrue(books.size() > 2); } @Test public void givenBookClient_shouldFindOneBook() throws Exception { Book book = bookClient.findByIsbn("0151072558").getBook(); assertThat(book.getAuthor(), containsString("Orwell")); } @Test public void givenBookClient_shouldPostBook() throws Exception { String isbn = UUID.randomUUID().toString(); Book book = new Book(isbn, "Me", "It's me!", null, null); bookClient.create(book); book = bookClient.findByIsbn(isbn).getBook(); assertThat(book.getAuthor(), is("Me")); } 

7. Lectures complémentaires

Si nous avons besoin d'une sorte de solution de secours en cas d'indisponibilité du service, nous pourrions ajouter HystrixFeign au chemin de classe et construire notre client avec HystrixFeign.builder () .

Consultez cette série de tutoriels dédiés pour en savoir plus sur Hystrix.

De plus, si nous souhaitons intégrer Spring Cloud Netflix Hystrix à Feign, il y a un article dédié ici.

De plus, il est également possible d'ajouter un équilibrage de charge côté client et / ou une découverte de service à notre client.

Nous pourrions y parvenir en ajoutant Ribbon à notre classpath et en utilisant le générateur comme ceci:

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

Pour la découverte de services, nous devons développer notre service avec Spring Cloud Netflix Eureka activé. Ensuite, intégrez simplement avec Spring Cloud Netflix Feign. En conséquence, nous obtenons gratuitement l'équilibrage de la charge du ruban. Pour en savoir plus, cliquez ici.

8. Conclusion

Dans cet article, nous avons expliqué comment créer un client HTTP déclaratif à l'aide de Feign pour consommer des API textuelles.

Comme d'habitude, tous les exemples de code présentés dans ce didacticiel sont disponibles à l'adresse over sur GitHub.