Привет, Хабр!
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
Отправка запросов
Остальной код можно посмотреть, перейдя по ссылке: https://github.com/gibkin/graphql-sqpr-spring-boot-starter