Open In App

Spring Boot - GraphQL Integration

Last Updated : 21 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

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.

Project Metadata

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.

Dependencies

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:

Project Folder Structure

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.

Application Logs
Application Started

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,

Query Response

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.

Next Article

Similar Reads