GraphQL + SPQR + Spring Boot Starter 2021

от автора

Привет, Хабр!

GraphQL — это язык запросов к API-интерфейсам. Он отображает предоставляемые сервером данные, чтобы клиент смог выбрать именно то, что ему нужно. GraphQL SPQR призван упростить добавление GraphQL API в любой Java-проект. SPQR работает динамически, генерируя схему GraphQL из кода Java, посредством аннотаций. Перейдем к самой сути!

Настройка проекта / Зависимости

Добавьте следующие зависимости в ваш maven проект:

<dependency>     <groupId>io.leangen.graphql</groupId>     <artifactId>graphql-spqr-spring-boot-starter</artifactId>     <version>0.0.6</version> </dependency> <dependency>     <groupId>com.graphql-java</groupId>     <artifactId>graphiql-spring-boot-starter</artifactId>     <version>5.0.2</version> </dependency>

Чтобы понять основные подходы SpqrAutoConfigurationрегистрирует компонент для каждой из трех встроенных ResolverBuilderреализаций:

  • AnnotatedResolverBuilder— предоставляет только методы, аннотированные @GraphQLQuery@GraphQLMutationили@GraphQLSubscription

  • PublicResolverBuilder— предоставляет все publicметоды из исходного класса операций (возвращаемые методы voidсчитаются мутациями)

  • BeanResolverBuilder— предоставляет все геттеры как запросы и сеттеры как мутации (возвращаемые геттеры Publisher<T>считаются подписками)

Также возможно реализовать собственные, реализовав свой ResolverBuilder интерфейс.

Описание основных аннотаций SPQR

@GraphQLApi— аналог контроллера, в котором определены Query и Mutation.

@GraphQLQuery — QUERY, аналог read запросов

@GraphQLMutation— MUTATION, аналог create/delete/update запросов

Остальные аннотации будут описаны ниже.

Описание сущности

Сущность банковский счет имеет номер счета (numberAccount), валюту (currency) и текущий счет (balance).

@Getter @Setter @Entity @Table(name = "bank_account") @FieldDefaults(level = AccessLevel.PRIVATE) @NoArgsConstructor public class BankAccountEntity {     @Id     String numberAccount;          Currency currency;      BigDecimal balance; } 

Опишем dto для работы с этой сущностью:

@Getter @Setter @FieldDefaults(level = AccessLevel.PRIVATE) public class BankAccountDto {     @GraphQLId     String numberAccount;      @NotNull     @GraphQLScalar     @GraphQLInputField     Currency currency;      @NotNull     @GraphQLInputField     BigDecimal balance; }

Здесь аннотация @GraphQLInputField говорит GraphQL, что текущее поле будет полем для обновления или ввода. Попрошу заметить, что у поля currency стоит аннотация @GraphQLScalar — один из способов реализовать сложный скаляр.

package ru.bank.web.dataFetcher;  import io.leangen.graphql.annotations.GraphQLArgument; import io.leangen.graphql.annotations.GraphQLMutation; import io.leangen.graphql.annotations.GraphQLNonNull; import io.leangen.graphql.annotations.GraphQLQuery; import io.leangen.graphql.spqr.spring.annotations.GraphQLApi; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Component; import ru.bank.business.service.BankAccountService; import ru.bank.web.dto.BankAccountDto; import ru.bank.web.dto.DispatchMoneyDto;  import java.util.List;  @RequiredArgsConstructor @Component @GraphQLApi public class BankAccountDataFetcher {     private final BankAccountService service;      @GraphQLQuery(name = "getAllBalance")     public List<BankAccountDto> getAll(@GraphQLArgument(name = "page")Pageable pageable) {         return service.getAll(pageable);     }      @GraphQLMutation(name = "createBankAccount", description = "create a new bank account")     public BankAccountDto createBankAccount(@GraphQLArgument(name = "createBankAccountInput") @GraphQLNonNull BankAccountDto bankAccount) {         return service.create(bankAccount);     }      @GraphQLMutation(name = "dispatchMoney", description = "dispatch money")     public void dispatchMoney(@GraphQLArgument(name = "createDispatchMoneyInput") @GraphQLNonNull DispatchMoneyDto dispatchMoneyDto) {         service.dispatchMoney(dispatchMoneyDto);     }      @GraphQLMutation(name = "removeBankAccount", description = "remove bank account")     public void removeBankAccount(@GraphQLNonNull String numberAccount) {         service.remove(numberAccount);     } } 

Параметр аннотации @GraphQLMutation name — указывает имя метода для GraphQL, а description — соответственно описание метода для graphiql

Отправка запросов

Отправка Query с пагинацией для получения данных по аккаунтам
Отправка Query с пагинацией для получения данных по аккаунтам
Отправка Mutation для удаления аккаунта по ключу
Отправка Mutation для удаления аккаунта по ключу
Отправка Mutation для создания нового аккаунта
Отправка Mutation для создания нового аккаунта

Остальной код можно посмотреть, перейдя по ссылке: https://github.com/gibkin/graphql-sqpr-spring-boot-starter


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


Комментарии

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

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