GraphQL + SPQR + Spring Boot Starter 2021
Project setup / Dependencies
Add the following dependencies to your maven project:
<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>
To understand the main approaches SpqrAutoConfiguration
registers a component for each of the three built-in ResolverBuilder
implementations:
AnnotatedResolverBuilder
– only provides methods annotated@GraphQLQuery
,@GraphQLMutation
or@GraphQLSubscription
PublicResolverBuilder
– provides everythingpublic
methods from the original operation class (return methodsvoid
are considered mutations)BeanResolverBuilder
– provides all getters as requests and setters as mutations (returned gettersPublisher<T>
count as subscriptions)
It is also possible to implement your own by implementing your ResolverBuilder interface.
Description of the main SPQR annotations
@ GraphQLApi is an analogue of a controller in which Query and Mutation are defined.
@GraphQLQuery – QUERY, analog of read queries
@ GraphQLMutation- MUTATION, analogue of create / delete / update queries
The rest of the annotations will be described below.
Description of the entity
The bank account entity has an account number (numberAccount), a currency (currency) and a current account (balance).
@Getter
@Setter
@Entity
@Table(name = "bank_account")
@FieldDefaults(level = AccessLevel.PRIVATE)
@NoArgsConstructor
public class BankAccountEntity {
@Id
String numberAccount;
Currency currency;
BigDecimal balance;
}
Let’s describe the dto for working with this entity:
@Getter
@Setter
@FieldDefaults(level = AccessLevel.PRIVATE)
public class BankAccountDto {
@GraphQLId
String numberAccount;
@NotNull
@GraphQLScalar
@GraphQLInputField
Currency currency;
@NotNull
@GraphQLInputField
BigDecimal balance;
}
Here, the @GraphQLInputField annotation tells GraphQL that the current field will be the field to update or enter. Please note that the currency field has the @GraphQLScalar annotation – one of the ways to implement a complex scalar.
@RequiredArgsConstructor
@Component
@GraphQLApi
public class BankAccountDataFetcher {
private final BankAccountService service;
@GraphQLQuery(name = "getAllBalance")
public List<BankAccountDto> getAll() {
return service.getAll();
}
@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);
}
}
The @GraphQLMutation annotation parameter name – specifies the method name for GraphQL, and description – respectively the description of the method for graphiql
Sending requests
The rest of the code can be viewed by following the link: https://github.com/gibkin/graphql-sqpr-spring-boot-starter