Einführung in Feign

1. Übersicht

In diesem Tutorial stellen wir Feign vor - einen deklarativen HTTP-Client, der von Netflix entwickelt wurde.

Feign zielt darauf ab, HTTP-API-Clients zu vereinfachen. Einfach ausgedrückt, der Entwickler muss nur eine Schnittstelle deklarieren und mit Anmerkungen versehen, während die eigentliche Implementierung zur Laufzeit bereitgestellt wird.

2. Beispiel

In diesem Lernprogramm wird eine Beispiel-Buchhandlungsanwendung verwendet, die den REST-API-Endpunkt verfügbar macht.

Wir können das Projekt einfach klonen und lokal ausführen:

mvn install spring-boot:run

3. Setup

Fügen wir zunächst die erforderlichen Abhängigkeiten hinzu:

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

Neben der Feign-Core-Abhängigkeit (die ebenfalls berücksichtigt wird) werden wir einige Plugins verwenden, insbesondere: Feign-Okhttp für die interne Verwendung des OkHttp-Clients von Square, um Anforderungen zu stellen, Feign-Gson für die Verwendung von Googles GSON als JSON-Prozessor und Feign- slf4j für die Verwendung der Simple Logging Facade zum Protokollieren von Anforderungen.

Um tatsächlich eine Protokollausgabe zu erhalten, benötigen wir unsere bevorzugte, von SLF4J unterstützte Logger-Implementierung im Klassenpfad.

Bevor wir mit der Erstellung unserer Client-Oberfläche fortfahren, richten wir zunächst ein Buchmodell für die Speicherung der Daten ein:

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

ANMERKUNG: Ein JSON-Prozessor benötigt mindestens einen Konstruktor ohne Argumente.

Tatsächlich ist unser REST-Anbieter eine hypermediengesteuerte API , daher benötigen wir zusätzlich eine einfache Wrapper-Klasse:

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

Hinweis: Wir ' ll das halten BookResource einfach , weil unsere Probe Feign Client von Hypermedia - Funktionen profitieren nicht!

4. Serverseite

Um zu verstehen, wie ein Feign-Client definiert wird, werden zunächst einige der von unserem REST-Anbieter unterstützten Methoden und Antworten untersucht.

Probieren wir es mit einem einfachen Curl-Shell-Befehl aus, um alle Bücher aufzulisten. Wir müssen daran denken, allen Aufrufen / api voranzustellen , was der Servlet-Kontext der Anwendung ist:

curl //localhost:8081/api/books

Als Ergebnis erhalten wir ein vollständiges Buch-Repository, das als JSON dargestellt wird:

[ { "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" } ] } ]

Wir können auch einzelne Buchressourcen abfragen , indem wir die ISBN an eine Get-Anfrage anhängen:

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

5. Kunden vortäuschen

Lassen Sie uns abschließend unseren Feign-Client definieren.

Wir werden die Annotation @RequestLine verwenden , um das HTTP-Verb und einen Pfadteil als Argument anzugeben. Die Parameter werden mithilfe der Annotation @Param modelliert :

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); }

ANMERKUNG : Feign-Clients können nur zum Verwenden von textbasierten HTTP-APIs verwendet werden. Dies bedeutet, dass sie keine Binärdaten verarbeiten können, z. B. Datei-Uploads oder -Downloads.

Das ist alles! Jetzt verwenden wir Feign.builder () , um unseren schnittstellenbasierten Client zu konfigurieren. Die eigentliche Implementierung wird zur Laufzeit bereitgestellt:

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 unterstützt verschiedene Plugins wie JSON / XML-Encoder und -Decoder oder einen zugrunde liegenden HTTP-Client zum Erstellen der Anforderungen.

6. Unit Test

Lassen Sie uns drei Testfälle erstellen, um unseren Kunden zu testen. Beachten Sie, dass wir statische Importe für org.hamcrest.CoreMatchers. * Und org.junit.Assert. * Verwenden :

@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. Weiterführende Literatur

Wenn wir im Falle einer Nichtverfügbarkeit des Dienstes eine Art Fallback benötigen, können wir HystrixFeign zum Klassenpfad hinzufügen und unseren Client mit HystrixFeign.builder () erstellen .

In dieser speziellen Tutorial-Reihe erfahren Sie mehr über Hystrix.

Wenn wir Spring Cloud Netflix Hystrix in Feign integrieren möchten, finden Sie hier einen speziellen Artikel.

Darüber hinaus ist es auch möglich, unserem Client einen clientseitigen Lastausgleich und / oder eine Serviceerkennung hinzuzufügen.

Wir könnten dies erreichen, indem wir Ribbon zu unserem Klassenpfad hinzufügen und den Builder wie folgt verwenden:

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

Für die Serviceerkennung müssen wir unseren Service mit aktiviertem Spring Cloud Netflix Eureka aufbauen. Dann einfach in Spring Cloud Netflix Feign integrieren. Als Ergebnis erhalten wir einen kostenlosen Ribbon Load Balancing. Mehr dazu finden Sie hier.

8. Fazit

In diesem Artikel haben wir erklärt, wie Sie mit Feign einen deklarativen HTTP-Client erstellen, um textbasierte APIs zu verwenden.

Wie üblich sind alle in diesem Tutorial gezeigten Codebeispiele auf GitHub verfügbar.