1. 개요
이 튜토리얼에서는 Netflix에서 개발 한 선언적 HTTP 클라이언트 인 Feign을 소개 합니다.
Feign은 HTTP API 클라이언트를 단순화하는 것을 목표로합니다. 간단히 말해서 개발자는 실제 구현이 런타임에 프로비저닝되는 동안 인터페이스를 선언하고 어노테이션을 달기 만하면됩니다.
2. 예
이 튜토리얼 전체 에서 REST API 엔드 포인트를 노출 하는 예제 서점 애플리케이션 을 사용합니다.
프로젝트를 쉽게 복제하고 로컬에서 실행할 수 있습니다.
mvn install spring-boot:run
3. 설정
먼저 필요한 의존성을 추가해 보겠습니다.
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<version>10.11</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-gson</artifactId>
<version>10.11</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-slf4j</artifactId>
<version>10.11</version>
</dependency>
외에 체하다 코어 (도에서 당기면) 의존성, 우리는 특히 몇 가지 플러그인을 사용합니다 : 체하다 - okhttp을 내부적으로 광장의 사용에 대한 OkHttp의 요청하도록 클라이언트를 체하다 - GSON JSON 프로세서와 구글의 GSON을 사용 feign-을 요청을 기록하기 위해 Simple Logging Facade 를 사용하기위한 slf4j .
실제로 일부 로그 출력을 얻으려면 클래스 경로에서 선호하는 SLF4J 지원 로거 구현이 필요합니다.
클라이언트 인터페이스를 만들기 전에 먼저 데이터를 보관 하기위한 Book 모델을 설정합니다 .
public class Book {
private String isbn;
private String author;
private String title;
private String synopsis;
private String language;
// standard constructor, getters and setters
}
참고 : JSON 프로세서에는 최소한 "인수 없음 생성자"가 필요합니다.
사실, 우리의 REST 공급자는이다 하이퍼 미디어 기반의 API는 , 우리가 추가로 간단한 래퍼 클래스가 필요합니다 그래서 :
public class BookResource {
private Book book;
// standard constructor, getters and setters
}
참고 : 우리는 ' 킵 것이다 BookResource의 우리의 샘플 척하기 클라이언트 하이퍼 미디어 기능을 활용할 수 없기 때문에 간단하게!
4. 서버 측
Feign 클라이언트를 정의하는 방법을 이해하기 위해 먼저 REST 공급자가 지원하는 몇 가지 메서드와 응답을 살펴 보겠습니다.
모든 책을 나열하기 위해 간단한 curl shell 명령으로 시도해 봅시다. 모든 호출에 / api 접두사를 붙이는 것을 기억해야합니다 . 이는 애플리케이션의 servlet-context입니다.
curl http://localhost:8081/api/books
결과적으로 JSON으로 표시된 완전한 책 저장소를 얻을 수 있습니다.
[
{
"book": {
"isbn": "1447264533",
"author": "Margaret Mitchell",
"title": "Gone with the Wind",
"synopsis": null,
"language": null
},
"links": [
{
"rel": "self",
"href": "http://localhost:8081/api/books/1447264533"
}
]
},
...
{
"book": {
"isbn": "0451524934",
"author": "George Orwell",
"title": "1984",
"synopsis": null,
"language": null
},
"links": [
{
"rel": "self",
"href": "http://localhost:8081/api/books/0451524934"
}
]
}
]
가져 오기 요청에 ISBN을 추가하여 개별 도서 리소스를 쿼리 할 수도 있습니다 .
curl http://localhost:8081/api/books/1447264533
5. Feign 클라이언트
마지막으로 Feign 클라이언트를 정의하겠습니다.
우리는 사용합니다 @RequestLine의 는 HTTP 동사 및 인수로 경로 부분을 지정하는 어노테이션을. 매개 변수는 @Param 어노테이션을 사용하여 모델링 됩니다.
public interface BookClient {
@RequestLine("GET /{isbn}")
BookResource findByIsbn(@Param("isbn") String isbn);
@RequestLine("GET")
List<BookResource> findAll();
@RequestLine("POST")
@Headers("Content-Type: application/json")
void create(Book book);
}
참고 : Feign 클라이언트는 텍스트 기반 HTTP API 만 사용하는 데 사용할 수 있습니다. 즉, 파일 업로드 또는 다운로드와 같은 이진 데이터를 처리 할 수 없습니다.
그게 다야! 이제 인터페이스 기반 클라이언트를 구성 하기 위해 Feign.builder () 를 사용할 것 입니다. 실제 구현은 런타임에 프로비저닝됩니다.
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, "http://localhost:8081/api/books");
Feign은 JSON / XML 인코더 및 디코더와 같은 다양한 플러그인 또는 요청을위한 기본 HTTP 클라이언트를 지원합니다.
6. 단위 테스트
클라이언트를 테스트하기 위해 세 가지 테스트 케이스를 만들어 보겠습니다. org.hamcrest.CoreMatchers. * 및 org.junit.Assert. *에 대해 정적 가져 오기를 사용합니다 .
@Test
public void givenBookClient_shouldRunSuccessfully() throws Exception {
List<Book> 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. 추가 읽기
서비스를 사용할 수없는 경우 일종의 폴 백이 필요하면 HystrixFeign 을 클래스 경로에 추가 하고 HystrixFeign.builder ()로 클라이언트를 빌드 할 수 있습니다 .
Hystrix에 대해 자세히 알아 보려면 이 전용 자습서 시리즈 를 확인하십시오 .
또한 Spring Cloud Netflix Hystrix를 Feign과 통합하려는 경우 여기에 전용 기사가 있습니다 .
또한 클라이언트 측로드 밸런싱 및 / 또는 서비스 검색을 클라이언트에 추가 할 수도 있습니다.
클래스 경로에 리본 을 추가 하고 다음과 같이 빌더를 사용하여 이를 달성 할 수 있습니다.
BookClient bookClient = Feign.builder()
.client(RibbonClient.create())
.target(BookClient.class, "http://localhost:8081/api/books");
서비스 검색을 위해서는 Spring Cloud Netflix Eureka를 활성화하여 서비스를 구축해야합니다. 그런 다음 Spring Cloud Netflix Feign과 간단히 통합하십시오. 그 결과 리본로드 밸런싱이 무료로 제공됩니다. 이에 대한 자세한 내용은 여기에서 확인할 수 있습니다 .
8. 결론
이 기사에서는 텍스트 기반 API를 사용하기 위해 Feign을 사용하여 선언적 HTTP 클라이언트를 빌드하는 방법을 설명했습니다.
평소처럼이 자습서에 표시된 모든 코드 샘플 은 GitHub에서 사용할 수 있습니다.