Рубрики
Без рубрики

Вступление к симуляции

В этой статье представлен Feign, декларативный HTTP-клиент, который упрощает реализацию и поддержку усилий

Автор оригинала: baeldung.

1. Обзор

В этом уроке мы представим Feign – декларативный HTTP-клиент, разработанный Netflix.

Притворство направлено на упрощение клиентов HTTP API. Проще говоря, разработчику нужно только объявить и аннотировать интерфейс, в то время как фактическая реализация подготовлена во время выполнения.

2. Пример

На протяжении всего этого урока мы будем использовать пример приложения bookstore , которое предоставляет конечную точку REST API.

Мы можем легко клонировать проект и запускать его локально:

mvn install spring-boot:run

3. Настройка

Во-первых, давайте добавим необходимые зависимости:


    io.github.openfeign
    feign-okhttp
    10.11


    io.github.openfeign
    feign-gson
    10.11


    io.github.openfeign
    feign-slf4j
    10.11

Помимо зависимости feign-core (которая также включена), мы будем использовать несколько плагинов, особенно: feign-okhttp для внутреннего использования клиента Square OkHttp для выполнения запросов, feign-gson для использования GSON Google в качестве процессора JSON и feign-slf4j для использования фасада Simple Logging для регистрации запросов.

Чтобы действительно получить некоторые выходные данные журнала, нам понадобится наша любимая реализация регистратора с поддержкой 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
}

Примечание: Мы сохраним Книжный ресурс просто потому, что наш пример притворного клиента не использует возможности гипермедиа!

4. Серверная сторона

Чтобы понять, как определить Feignclient, мы сначала рассмотрим некоторые методы и ответы, поддерживаемые нашим поставщиком REST.

Давайте попробуем это с помощью простой команды оболочки curl, чтобы перечислить все книги. Нам нужно не забыть префиксировать все вызовы с помощью /api , который является контекстом сервлета приложения:

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 к запросу get:

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

5. Симулируйте Клиента

Наконец, давайте определим нашего Притворного клиента.

Мы будем использовать аннотацию @RequestLine , чтобы указать глагол HTTP и часть пути в качестве аргумента. Параметры будут смоделированы с помощью аннотации @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);
}

ПРИМЕЧАНИЕ: Притворные клиенты могут использоваться только для использования текстовых 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.Утверждение.* :

@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. Дальнейшее Чтение

Если нам нужен какой-то запасной вариант в случае недоступности службы, мы могли бы добавить HystrixFeign в путь к классу и построить наш клиент с помощью HystrixFeign.builder() .

Ознакомьтесь с этой специальной серией учебников, чтобы узнать больше о Hystrix.

Кроме того, если мы хотим интегрировать Spring Cloud Netflix Hystrix с Feign, здесь есть специальная статья .

Кроме того, к нашему клиенту также можно добавить балансировку нагрузки на стороне клиента и/или обнаружение служб.

Мы могли бы достичь этого, добавив Ribbon в ваш путь к классу и используя конструктор следующим образом:

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

Для обнаружения служб мы должны создать наш сервис с включенной поддержкой Spring Cloud Netflix Eureka. Затем просто интегрируйтесь с Spring Cloud Netflix. В результате мы получаем бесплатную балансировку нагрузки на ленту. Подробнее об этом можно узнать здесь .

8. Заключение

В этой статье мы объяснили, как создать декларативный HTTP-клиент, используя притворство для использования текстовых API.

Как обычно, все примеры кода, показанные в этом руководстве, доступны на GitHub.