Feign ist eine sehr einfache Java HTTP-Clientbibliothek. Bewertung von: star: 2745 auf github (Stand: 2. April 2018), daher scheint es sich um eine ziemlich genutzte Bibliothek zu handeln. Sie können eine HTTP-Anfrage mit sehr kurzem Code ausgeben. Der Fluss bei Verwendung von "Feign" ist wie folgt.
Die Nachteile sind, dass nur textbasierte HTTP-Anforderungen ausgegeben werden können und HTTP-Antworten nur auf BODY zugreifen können.
(Hinzugefügt am 08.04.2018) Es wird von der Standardeinstellung "Feign" nicht unterstützt, aber Sie können binäre HTTP-Anforderungen mit einem anderen Modul oder Ihrer eigenen Implementierung verarbeiten.
Fegin
ist so konfiguriert, dass die verwendeten Komponenten ausgetauscht werden können.
Dieses Mal werden wir "OkHttp", "Jackson" und "Logback" verwenden.
pom.xml
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<version>9.5.1</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
<version>9.5.1</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-slf4j</artifactId>
<version>9.5.1</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
Definieren Sie die API, die Sie als Schnittstelle aufrufen möchten.
Dieses Mal möchte ich den Fall des Aufrufs der unten gezeigten API betrachten.
Artikelnummer | Pfad | HTTP-Methode | Erläuterung |
---|---|---|---|
1 | /todos | GET | Holen Sie sich alle TODO |
2 | /todos/{todoId} | GET | Ruft das von todoId angegebene TODO ab |
3 | /todos | POST | Erstellen Sie ein TODO mit den übertragenen Daten Der Inhaltstyp ist application/json Zu |
4 | /todos/{todoId} | PUT | Aktualisieren Sie das von todoId angegebene TODO Der Inhaltstyp ist application/json Zu |
5 | /todos/{todoId} | DELETE | Löschen Sie das von todoId angegebene TODO |
Der API-Endpunkt (URL) lautet "http: // localhost: 8090 / todo-rest / api / v1".
TodoApi.java
package com.example.feign.demo;
import java.util.List;
import feign.Headers;
import feign.Param;
import feign.RequestLine;
public interface TodoApi {
@RequestLine("GET /todos")
List<Todo> findAll();
@RequestLine("GET /todos/{todoId}")
Todo getTodo(@Param("todoId") String todoId);
@RequestLine("POST /todos")
@Headers("Content-Type: application/json")
Todo createTodo(Todo todo);
@RequestLine("PUT /todos/{todoId}")
@Headers("Content-Type: application/json")
Todo updateTodo(@Param("todoId") String todoId, Todo todo);
@RequestLine("DELETE /todos/{todoId}")
void deleteTodo(@Param("todoId") String todoId);
}
Ich habe die API-Schnittstelle definiert, aber nicht ihre Implementierungsklasse. Eine Instanz der API wird mit Feign
erstellt.
Durch Aufrufen der API werden einfach die Methoden der Schnittstelle ausgeführt.
TodoApiDemo.java
package com.example.feign.demo;
import java.util.List;
import feign.Feign;
import feign.Logger;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import feign.okhttp.OkHttpClient;
import feign.slf4j.Slf4jLogger;
public class TodoApiDemo {
public static void main(String[] args) {
// 1. create instance of api interface with feign
TodoApi todoApi = Feign.builder() // builder call at first
.client(new OkHttpClient()) // use OkHttpClient of feign
.encoder(new JacksonEncoder()) // use Jackson of feign
.decoder(new JacksonDecoder()) // use Jackson of feign
.logger(new Slf4jLogger()) // use Slf4j of feign
.logLevel(Logger.Level.FULL) // setting log level to most detail
.target(TodoApi.class,
"http://localhost:8090/todo-rest/api/v1");
// 2. call api [GET /todos]
List<Todo> todos = todoApi.findAll();
System.out.println(todos);
}
}
Es wird eine dedizierte Konfigurationsmethode bereitgestellt, um eine Instanz mit dem Builder-Muster zu erstellen.
client
MethodeEncoder
MethodeDecoder
Methodelogger
MethodelogLevel
MethodeZiel
MethodeKlasse
der API-Schnittstelle definiert in [3. API-Schnittstelle definieren](# 3-API-Schnittstelle definieren)Der Aufruf ist nicht schwierig, da nur die Methode der API-Instanz aufgerufen wird. Als Referenz werde ich den Beispiel-API-Test beschreiben. Da der Zweck darin besteht, "Feign" zu verwenden, ist der Inhalt des Tests selbst angemessen.
TodoApiTest.java
package com.example.feign.demo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import java.util.Date;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import feign.Feign;
import feign.Logger;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import feign.okhttp.OkHttpClient;
import feign.slf4j.Slf4jLogger;
public class TodoApiTest {
// test api
TodoApi todoApi;
private <T> T factory(Class<T> apiType, String url) {
return Feign.builder() // builder call at first
.client(new OkHttpClient()) // use OkHttpClient of feign
.encoder(new JacksonEncoder()) // use Jackson of feign
.decoder(new JacksonDecoder()) // use Jackson of feign
.logger(new Slf4jLogger()) // use Slf4j
.logLevel(Logger.Level.FULL) // setting log level to most detail
.target(apiType, url);
}
@Before
public void setUp() throws Exception {
todoApi = factory(TodoApi.class,
"http://localhost:8090/todo-rest/api/v1");
}
@Test
public void testFindAll() {
List<Todo> todos = todoApi.findAll();
System.out.println(todos);
assertThat(todos.size(), is(2));
}
@Test
public void testCreateTodo() {
Todo todo = new Todo();
todo.setTodoTitle("hello");
Todo registeredTodo = todoApi.createTodo(todo);
System.out.println(registeredTodo);
}
@Test
public void testGetTodo() {
String todoId = "36e06987-ef33-436a-a2c6-d215096ee902";
Todo todo = todoApi.getTodo(todoId);
System.out.println(todo);
assertThat(todo.getTodoId(), is(todoId));
}
@Test
public void testUpdateTodo() {
String todoId = "36e06987-ef33-436a-a2c6-d215096ee902";
String title = "update......";
Todo todo = new Todo();
todo.setTodoId(todoId);
todo.setTodoTitle(title);
todo.setCreatedAt(new Date());
Todo updatedTodo = todoApi.updateTodo(todoId, todo);
System.out.println(updatedTodo);
assertThat(updatedTodo.getTodoId(), is(todoId));
assertThat(updatedTodo.getTodoTitle(), is(title));
assertThat(updatedTodo.isFinished(), is(true));
}
@Test
public void testDeleteTodo() {
String todoId = "36e06987-ef33-436a-a2c6-d215096ee902";
todoApi.deleteTodo(todoId);
System.out.println("ok");
}
}
Dieses Mal erklärte ich Feign, eine Bibliothek für den Java-HTTP-Client. Es ist eine sehr einfach zu verwendende Bibliothek, da fast die API-Schnittstelle definiert wird. Obwohl diesmal nicht erklärt, unterstützt "Feign" auch "JAXB" und "JAX-RS". Es gibt eine Einschränkung, dass nur textbasierte HTTP-Anforderungen verarbeitet werden können, aber ich wollte sie aktiv mit APIs verwenden, die davon nicht betroffen sind.
Recommended Posts