Spring Boot - GraphQL Integration
Last Updated :
21 Aug, 2024
GraphQL is a powerful query language for APIs that allows clients to request specific data in a single request. Unlike REST, which often requires multiple endpoints, GraphQL provides a single endpoint where clients can specify exactly what data they need. This reduces the number of requests and the amount of data transferred, making APIs more efficient and easier to use. Integrating GraphQL with Spring Boot enables the development of flexible and efficient APIs.
Key Components of GraphQL
- Schema: The schema defines the structure of the data that can be queried and includes types, queries, mutations, and subscriptions.
- Resolvers: Functions that handle the data fetching logic for the GraphQL server. Each field in a query is backed by a resolver.
- Query Execution: The server uses the schema to validate and parse the query, then executes it using resolvers and returns the data in JSON format.
Prerequisites:
- Basic knowledge of Java and Spring Boot.
- Familiarity with GraphQL concepts such as queries, mutations, and schemas.
- Maven for dependency management.
- Postman tool for testing the application.
- JDK and IntelliJ IDEA installed on your system.
Implementation of GraphQL Integration in Spring Boot Project
Step 1: Create a New Spring Boot Project
Create a new Spring Boot project using IntelliJ IDEA with the following options:
- Name:
spring-boot-graphql-example
- Language:
Java
- Type:
Maven
- Packaging:
Jar
Click on the Next button.
Step 2: Add the Dependencies
Add the following dependencies into the Spring Boot project.
- Spring for GraphQL
- Spring Data JPA
- MySQL Driver
- Lombok
- Spring Boot DevTools
- Spring Web
Click on the Create button.
These dependencies include essential libraries for Spring Boot, GraphQL integration, data persistence with JPA, MySQL database connectivity, and development tools.
Project Structure:
After creating the project, the folder structure will look like below:
Step 3: Configure Application Properties
Open the src/main/resources/application.properties
file and add the following MySQL and Hibernate configuration:
application.properties
spring.application.name=spring-boot-graphql-example
# MySQL Database Configuration
spring.datasource.url=jdbc:mysql://localhost:3306/testdb
spring.datasource.username=root
spring.datasource.password=mypassword
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# Hibernate Configuration
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
This configuration sets up the MySQL database connection and Hibernate settings. It specifies the database URL, username, password, and SQL visibility.
Step 4: Define the GraphQL Schema
Create a file named schema.graphqls
in the src/main/resources/graphql
directory with the following content:
schema.graphqls:
type Query {
getBookById(id: ID!): Book
}
type Book {
id: ID!
title: String!
author: String!
}
This schema defines the data structure for queries and mutations. It includes a Book
type and operations to retrieve and add books.
Step 5: Create the data SQL file
Create a file named data.sql
in the src/main/resources
directory with the following SQL statements:
INSERT INTO BOOK (ID, TITLE, AUTHOR) VALUES (1, 'Spring Boot GraphQL', 'John Doe');
INSERT INTO BOOK (ID, TITLE, AUTHOR) VALUES (2, 'Learning GraphQL', 'Jane Doe');
This SQL file provides initial data for the book
table. It inserts sample books into the database.
Step 6: Create the Book Entity
Create a new Java class Book
in the src/main/java/com/example/demo/model
package:
Java
package com.gfg.springbootgraphqlexample;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
@Entity
public class Book {
@Id
private Long id;
private String title;
private String author;
// Constructors, Getters, and Setters
public Book() {}
public Book(Long id, String title, String author) {
this.id = id;
this.title = title;
this.author = author;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.autho= author;
}
}
This entity class represents the Book
table in the database. It includes fields for id
, title
, and author
, with Lombok annotations to generate getters, setters, and constructors.
Step 7: Create the BookRepository Interface
Create a new Java interface BookRepository
in the src/main/java/com/example/demo/repository
package:
Java
package com.gfg.springbootgraphqlexample;
import org.springframework.data.jpa.repository.JpaRepository;
public interface BookRepository extends JpaRepository<Book, Long> {
}
This repository interface extends JpaRepository
to provide CRUD operations for the Book
entity.
Step 8: Create the BookResolver Class
Create a new Java class BookResolver
in the src/main/java/com/example/demo/resolver
package:
Java
package com.gfg.springbootgraphqlexample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
@Controller
public class BookResolver {
@Autowired
private BookRepository bookRepository;
@QueryMapping
public Book getBookById(@Argument Long id) {
return bookRepository.findById(id).orElse(null);
}
}
This class provides data fetchers for the GraphQL queries and mutations. It interacts with the BookRepository
to fetch and manipulate book data.
Step 9: Main class
The main class, SpringBootGraphqlExampleApplication
, is the entry point of the application:
Java
package com.gfg.springbootgraphqlexample;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootGraphqlExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootGraphqlExampleApplication.class, args);
}
}
pom.xml file:
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>3.3.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gfg</groupId>
<artifactId>spring-boot-graphql-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-graphql-example</name>
<description>spring-boot-graphql-example</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-graphql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- GraphQL Java Tools -->
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>11.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.graphql</groupId>
<artifactId>spring-graphql-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Step 10: Run the Application
Run the Spring Boot application on port 8080.
Step 11: Testing the Application
We can test the application using Postman by sending the following GraphQL query to,
http://localhost:8080/graphql
Query:
{
getBookById(id: 1) {
id
title
author
}
}
Response: The response should be a JSON object similar to below,
This example project demonstrates the basic setup for integrating the GraphQL with Spring Boot. With this setup, we can further expand the application by adding the more queries, mutations and reslovers to handle the various operations.
Benefits of Using GraphQL in Spring Boot
- Efficiency: GraphQL enables clients to specify exactly the data they need, which minimizes data transfer and enhances performance.
- Flexibility: With GraphQL, clients can easily modify their queries to include additional fields or related data without requiring changes to the API.
- Single Endpoint: Unlike REST, which might require multiple endpoints to fetch related data, GraphQL uses a single endpoint to handle all queries, simplifying API design.