Quick Guide to Integrating GraphQL with Spring Boot
This tutorial shows how to quickly add GraphQL support to a Spring Boot web project by creating a Maven project, adding custom dependencies, defining schema files, implementing resolvers and a controller, and testing query and mutation endpoints, all without using the official graphql‑java‑tools starter.
This article demonstrates a fast way to add GraphQL support to a Spring Boot web project, avoiding the official graphql-java-tools starter and using a more flexible configuration.
Quick start – generate a Spring Boot project with Spring Initializr, replace application.properties with application.yml, and add the required Maven dependencies.
Required Maven dependencies (pom.xml):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.6</version>
<relativePath/>
</parent>
<groupId>com.xuxd</groupId>
<artifactId>graphql.demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<lombok.version>1.18.20</lombok.version>
<graphql-java-tools.version>11.0.1</graphql-java-tools.version>
<gson.version>2.8.7</gson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>${graphql-java-tools.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>After adding the dependencies, a GraphQLProvider component creates the GraphQL instance, loads schema files ( base.graphqls and item.graphqls) and registers query and mutation resolvers.
@Component
public class GraphQLProvider {
private GraphQL graphQL;
@Autowired
private IItemService itemService;
@Bean
public GraphQL graphQL() {
return graphQL;
}
@PostConstruct
public void init() throws IOException {
GraphQLSchema graphQLSchema = SchemaParser.newParser()
.file("graphql/base.graphqls")
.resolvers(new Query(), new Mutation())
.file("graphql/item.graphqls")
.resolvers(new ItemResolver(itemService))
.build()
.makeExecutableSchema();
this.graphQL = GraphQL.newGraphQL(graphQLSchema).build();
}
}The schema files define the GraphQL types. base.graphqls declares the root Query and Mutation with a simple version field. item.graphqls extends these roots with item‑related queries and mutations and defines Item, ItemList, and Param types.
schema {
query: Query
mutation: Mutation
}
type Query {
version: String
}
type Mutation {
version: String
}
extend type Query {
queryItemList: ItemList
queryById(id: ID): Item
}
extend type Mutation {
updateName(param: Param): Item
}
type Item {
id: ID!
code: String!
name: String!
}
type ItemList {
itemList: [Item!]!
total: Int!
}
input Param {
id: ID!
name: String!
}The ItemResolver implements GraphQLQueryResolver and GraphQLMutationResolver, delegating the actual work to an IItemService implementation.
public class ItemResolver implements GraphQLQueryResolver, GraphQLMutationResolver {
private IItemService itemService;
public ItemResolver(IItemService itemService) {
this.itemService = itemService;
}
// queryItemList defined in item.graphqls
public ItemList queryItemList() {
return itemService.queryItemList();
}
public Item queryById(Long id) {
return itemService.queryById(id);
}
public Item updateName(Param param) {
return itemService.updateName(param);
}
}A simple GraphqlController exposes a /graphql POST endpoint that builds an ExecutionInput from the incoming GraphqlRequest, executes it with the GraphQL bean, and returns either the data or any errors.
@RestController
@RequestMapping("/graphql")
public class GraphqlController {
@Autowired
private GraphQL graphQL;
@PostMapping
public Object execute(@RequestBody GraphqlRequest request) {
ExecutionInput executionInput = ExecutionInput.newExecutionInput()
.query(request.getQuery())
.variables(request.getVariables())
.build();
ExecutionResult executionResult = graphQL.execute(executionInput);
List<GraphQLError> errors = executionResult.getErrors();
if (errors != null && !errors.isEmpty()) {
Map<String, Object> result = new HashMap<>();
result.put("errors", errors);
return result;
}
return executionResult.getData();
}
}Three example operations are tested: fetching the item list, querying an item by ID, and updating an item's name. The article includes screenshots of the JSON responses showing successful queries and mutations.
With the configuration complete, the project can be started and further business logic added.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
