Spring Boot GraphQL CRUD Example

GraphQL is a powerful query language for APIs that allows clients to request exactly the data they need, and nothing more. Integrating GraphQL with Spring Boot 3.2 allows you to build flexible and efficient APIs. This tutorial will guide you through the process of setting up a Spring Boot 3.2 application with GraphQL to perform CRUD operations.

Prerequisites

  • JDK 17 or later
  • Maven or Gradle
  • IDE (IntelliJ IDEA, Eclipse, etc.)

Step 1: Set Up a Spring Boot Project

1.1 Create a New Spring Boot Project

Use Spring Initializr to create a new project with the following dependencies:

  • Spring Web
  • Spring Data JPA
  • H2 Database
  • GraphQL Spring Boot Starter

Download and unzip the project, then open it in your IDE.

1.2 Configure application.properties

Set up the application properties for your project. This file is located in the src/main/resources directory.

# src/main/resources/application.properties

# Server configuration
server.port=8080

# H2 Database configuration
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.datasource.platform=h2

# JPA configuration
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

# GraphQL configuration
graphql.servlet.mapping=/graphql
graphql.servlet.enabled=true
graphql.playground.enabled=true
graphql.playground.mapping=/playground

Explanation:

  • Configures the H2 in-memory database.
  • Enables SQL logging.
  • Sets up GraphQL endpoints and GraphQL Playground for testing.

Step 2: Define the Entity Class

2.1 Create the Book Entity

Create an entity class to represent a book in the database.

package com.example.demo.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    private String author;
    private String publisher;

    // Getters and setters
    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.author = author;
    }

    public String getPublisher() {
        return publisher;
    }

    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }
}

Explanation:

  • @Entity: Specifies that the class is an entity and is mapped to a database table.
  • @Id and @GeneratedValue: Indicates the primary key and its generation strategy.

Step 3: Create the Repository Interface

3.1 Create the BookRepository

Create a repository interface to perform CRUD operations on the Book entity.

package com.example.demo.repository;

import com.example.demo.entity.Book;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
}

Explanation:

  • @Repository: Indicates that the interface is a Spring Data repository.
  • JpaRepository<Book, Long>: Provides CRUD operations for the Book entity.

Step 4: Define GraphQL Schema

4.1 Create the schema.graphqls File

Create a schema.graphqls file in the src/main/resources directory.

type Book {
    id: ID!
    title: String!
    author: String!
    publisher: String!
}

type Query {
    getBooks: [Book]
    getBook(id: ID!): Book
}

type Mutation {
    addBook(title: String!, author: String!, publisher: String!): Book
    updateBook(id: ID!, title: String, author: String, publisher: String): Book
    deleteBook(id: ID!): String
}

Explanation:

  • Defines the Book type and its fields.
  • Defines the Query type with getBooks and getBook queries.
  • Defines the Mutation type with addBook, updateBook, and deleteBook mutations.

Step 5: Implement GraphQL Resolvers

5.1 Create the BookResolver

Create a resolver class to handle GraphQL queries and mutations.

package com.example.demo.resolver;

import com.example.demo.entity.Book;
import com.example.demo.repository.BookRepository;
import graphql.kickstart.tools.GraphQLMutationResolver;
import graphql.kickstart.tools.GraphQLQueryResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;

@Component
public class BookResolver implements GraphQLQueryResolver, GraphQLMutationResolver {

    @Autowired
    private BookRepository bookRepository;

    // Queries
    public List<Book> getBooks() {
        return bookRepository.findAll();
    }

    public Optional<Book> getBook(Long id) {
        return bookRepository.findById(id);
    }

    // Mutations
    public Book addBook(String title, String author, String publisher) {
        Book book = new Book();
        book.setTitle(title);
        book.setAuthor(author);
        book.setPublisher(publisher);
        return bookRepository.save(book);
    }

    public Book updateBook(Long id, String title, String author, String publisher) {
        Optional<Book> optionalBook = bookRepository.findById(id);
        if (optionalBook.isPresent()) {
            Book book = optionalBook.get();
            if (title != null) book.setTitle(title);
            if (author != null) book.setAuthor(author);
            if (publisher != null) book.setPublisher(publisher);
            return bookRepository.save(book);
        }
        return null;
    }

    public String deleteBook(Long id) {
        bookRepository.deleteById(id);
        return "Book deleted successfully";
    }
}

Explanation:

  • Implements GraphQLQueryResolver and GraphQLMutationResolver to handle GraphQL queries and mutations.
  • Provides methods to perform CRUD operations on the Book entity.

Step 6: Running and Testing the Application

6.1 Run the Application

Run the Spring Boot application using your IDE or the command line:

./mvnw spring-boot:run

6.2 Access GraphQL Playground

Open your browser and navigate to http://localhost:8080/playground. This will open the GraphQL Playground, where you can test your queries and mutations.

6.3 Test Queries and Mutations

Add a Book

mutation {
  addBook(title: "Spring Boot in Action", author: "Craig Walls", publisher: "Manning Publications") {
    id
    title
    author
    publisher
  }
}

Get All Books

query {
  getBooks {
    id
    title
    author
    publisher
  }
}

Get a Book by ID

query {
  getBook(id: 1) {
    id
    title
    author
    publisher
  }
}

Update a Book

mutation {
  updateBook(id: 1, title: "Spring Boot in Practice", author: "Craig Walls") {
    id
    title
    author
    publisher
  }
}

Delete a Book

mutation {
  deleteBook(id: 1)
}

Conclusion

In this tutorial, you have learned how to set up a Spring Boot 3.2 application with GraphQL to perform CRUD operations. We covered:

  • Setting up a Spring Boot project.
  • Defining an entity class and repository.
  • Creating a GraphQL schema.
  • Implementing GraphQL resolvers for queries and mutations.
  • Running and testing the application using GraphQL Playground.

By following these steps, you can build flexible and efficient APIs using GraphQL with Spring Boot 3.2.


Comments