Пишем простую интеграцию с GitHub используя feign и jsonschema2pojo maven plugin

—

от автора

В эпоху микросервисов приходится все чаще и чаще писать интеграции для их взаимодействия как между собой, так и со сторонними системами. Кто-то создаёт отдельные библиотеки с интеграцией и переиспользует их в нескольких микросервисах, кто-то захламляет проект огромным количеством POJO классов, некоторые же создают один POJO класс с множеством вложенных классов. В этой статье я хотел бы поделиться подходом, используя который вы сможете спрятать большую часть кода, которая мешает чтению и пониманию проекта.

Для примера мы будем использовать интеграцию с API GitHub и привычные Spring аннотации для описания нашего клиента.

Подключаем зависимости

Добавим feign-spring4 для поддержки генерации клиента на основе spring аннотаций.

<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-spring4</artifactId> <version>${feign.version}</version> </dependency>

Добавляем feign-jackson для поддержки аннотаций, которые будут в сгенерированных POJO классах.

<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-jackson</artifactId> <version>${feign.version}</version> </dependency>

Добавляем плагин для генерации POJO классов

В секцию plugins добавляем конфигурацию для jsonschema2pojo-maven-plugin. Указываем, где у нас хранятся json схемы, какое название пакета будет использоваться в сгенерированных классах и отключаем добавление дополнительных полей, чтобы игнорировать те, которые мы не используем.

<build> <plugins> <plugin> <groupId>org.jsonschema2pojo</groupId> <artifactId>jsonschema2pojo-maven-plugin</artifactId> <version>1.2.1</version> <configuration> <sourceDirectory>${basedir}/src/main/resources/schema</sourceDirectory> <targetPackage>com.example.types</targetPackage> <includeAdditionalProperties>false</includeAdditionalProperties> </configuration> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> </plugin> </plugins> </build>

Опишем json схему, по которой будут генерироваться наши POJO классы. Для того, чтобы генератор не пропустил классы из definitions, нужно добавить ссылки на них в properties.

{   "$schema": "http://json-schema.org/draft-07/schema#",   "description" : "Definition of GitHubApi",   "type": "object",   "properties" : {     "contributor" : {       "type" : "object",       "$ref" : "#/definitions/Contributor"     },     "issue" : {       "type" : "object",       "$ref" : "#/definitions/Issue"     }   },   "definitions": {     "Contributor" : {       "type" : "object",       "properties": {         "login": {           "type": "string"         },         "contributions": {           "type": "integer"         }       }     },     "Issue" : {       "type" : "object",       "properties": {         "title": {           "type": "string"         },         "body": {           "type": "string"         },         "labels": {           "type": "array",           "items": {             "type": "object",             "properties": {               "name": {                 "type": "string"               }             }           }         },         "user": {           "type" : "object",           "$ref" : "#/definitions/User"         }       }     },     "User" : {       "type" : "object",       "properties": {         "login": {           "type": "string"         },         "avatar_url": {           "type": "string"         }       }     }   } } 

Для упрощения создания схемы можно воспользоваться онлайн генератором схемы из json.

Переходим к описанию интеграции

Создадим простой интерфейс для описания конечных URI для получения данных.

interface GitHubApi {     @GetMapping("/repos/{owner}/{repo}/contributors")     List<Contributor> contributors(@PathVariable("owner") String owner, @PathVariable("repo") String repo);     @GetMapping("/repos/{owner}/{repo}/issues")     List<Issue> issues(@PathVariable("owner") String owner, @PathVariable("repo") String repo); }

Создаем клиента для обращения к GitHub. Выбираем JacksonDecoder для поддержки аннотаций в POJO классах (таких как @JsonProperty). Добавляем SpringContract для использования spring аннотаций (@GetMapping, @PathVariable).

GitHubApi github = Feign.builder()             .decoder(new JacksonDecoder())             .contract(new SpringContract())             .target(GitHubApi.class, "https://api.github.com");

Далее мы сможем использовать этот клиент для обращения к таким методам, как contributors и issues. При необходимости можно провести более глубокую настройку. Например, можно добавить логирование каждого запроса / ответа сервера, количество повторных вызовов в случае ошибок и многое другое.

Заключение

Безусловно, можно использовать множество реализаций генерации кода, таких как OpenAPI. Данный подход дает гибкость при описании POJO и простой настройке клиента.

Полезные ссылки


ссылка на оригинал статьи https://habr.com/ru/articles/766522/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *