Building a Spring Boot API with GraphQL and MySQL
This guide will walk you through creating a Spring Boot API using GraphQL and MySQL. We’ll cover everything from database configuration to defining complex GraphQL queries and mutations. While beginner-friendly, the further tutorial parts also delves into some advanced queries for real-world applications.
Introduction to GraphQL
GraphQL, developed by Facebook, is a query language that allows clients to specify precisely the data they need. It provides a more flexible and efficient choice to REST APIs, particularly for applications requiring nested or complex data structures.
Key Concepts of GraphQL
- Query: Used to fetch data
- Mutation: Used to create, update or delete data
- Schema: Defines the API structure, including data types and operations (queries/mutations)
GraphQL’s ability to precisely define and retrieve data enhances performance and streamlines development, making it a popular choice for modern APIs.
Requirements
- Java 17 or higher
- MySQL 8
- Maven
- Any Java IDE (IntelliJ IDEA for the sake of this tutorial)
- Basic understanding of Java and Spring Boot
Creating the Database
Open your MySQL command line or GUI (e.g., MySQL Workbench) and create a new database for the application.
CREATE DATABASE graphql_db;
Setting Up the Spring Boot Project
Step 1: Create a New Spring Boot Project
- Visit Spring Initializr
- Configure the project as shown below
- Project: Maven Project
- Language: Java
- Spring Boot Version: Latest stable version
- Dependencies: Spring Web, Spring Data JPA, MySQL Driver and GraphQL
- Click Generate to download the project and unzip it
- Open it in an IDE and build the project using maven
Step 2: Configure MySQL Connection
Open src/main/resources/application.properties and add the following configurations
spring.application.name=graphqldemo
# MySQL Configuration
spring.datasource.url=jdbc:mysql://localhost:3306/graphql_db
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# JPA (Hibernate) Configuration
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
# Enable GraphiQL UI
spring.graphql.graphiql.enabled=true
Step 3: Defining the GraphQL Schema
This schema defines:
Queries to retrieve a single user (getUser), retrieve all users (getAllUsers), and a basic greeting (hello).
Mutations to create, update, and delete users.
User Type: A data structure representing user information, with fields like id, name, email, age, address, phoneNumber, and createdDate.
type Query {
hello: String
getUser(id: ID!): User
getAllUsers: [User]
}
type Mutation {
createUser(name: String!, email: String!, age: Int, address: String, phoneNumber: String): User
updateUser(id: ID!, name: String, email: String, age: Int, address: String, phoneNumber: String): User
deleteUser(id: ID!): Boolean
}
type User {
id: ID!
name: String!
email: String!
age: Int
address: String
phoneNumber: String
createdDate: String
}
Creating the Backend Components
Step 1: Define the User Model
Create User.java in src/main/java/com/easycode/graphqldemo/model/
package com.easycode.graphqldemo.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Data;
import java.time.LocalDate;
@Data
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private Integer age;
private String address;
private String phoneNumber;
private LocalDate createdDate = LocalDate.now();
}
Step 2: Create the User Repository
Create UserRepository.java in src/main/java/com/easycode/graphqldemo/repository/
package com.easycode.graphqldemo.repository;
import com.easycode.graphqldemo.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
Step 3: Create the User Service
Create UserService.java in src/main/java/com/easycode/graphqldemo/service/
package com.easycode.graphqldemo.service;
import com.easycode.graphqldemo.model.User;
import com.easycode.graphqldemo.repository.UserRepository;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User getUser(Long id) {
return userRepository.findById(id).orElse(null);
}
public List<User> getAllUsers() {
return userRepository.findAll();
}
public User createUser(String name, String email, Integer age, String address, String phoneNumber) {
User user = new User();
user.setName(name);
user.setEmail(email);
user.setAge(age);
user.setAddress(address);
user.setPhoneNumber(phoneNumber);
return userRepository.save(user);
}
public User updateUser(Long id, String name, String email, Integer age, String address, String phoneNumber) {
Optional<User> existingUser = userRepository.findById(id);
if (existingUser.isPresent()) {
User user = existingUser.get();
if (name != null) user.setName(name);
if (email != null) user.setEmail(email);
if (age != null) user.setAge(age);
if (address != null) user.setAddress(address);
if (phoneNumber != null) user.setPhoneNumber(phoneNumber);
return userRepository.save(user);
}
return null;
}
public boolean deleteUser(Long id) {
if (userRepository.existsById(id)) {
userRepository.deleteById(id);
return true;
}
return false;
}
}
Step 4: Create the GraphQL Resolver Controller
With Spring GraphQL, resolvers are simply Spring components annotated with @Controller and methods annotated with @QueryMapping or @MutationMapping.
Create UserController.java in src/main/java/com/easycode/graphqldemo/controller/
package com.easycode.graphqldemo.controller;
import com.easycode.graphqldemo.model.User;
import com.easycode.graphqldemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.MutationMapping;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
import java.util.List;
@Controller
public class UserController {
@Autowired
private UserService userService;
@QueryMapping
public String hello() {
return "Hello, GraphQL!";
}
@QueryMapping
public User getUser(@Argument Long id) {
return userService.getUser(id);
}
@QueryMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
@MutationMapping
public User createUser(@Argument String name, @Argument String email, @Argument Integer age, @Argument String address, @Argument String phoneNumber) {
return userService.createUser(name, email, age, address, phoneNumber);
}
@MutationMapping
public User updateUser(@Argument Long id, @Argument String name, @Argument String email, @Argument Integer age, @Argument String address, @Argument String phoneNumber) {
return userService.updateUser(id, name, email, age, address, phoneNumber);
}
@MutationMapping
public boolean deleteUser(@Argument Long id) {
return userService.deleteUser(id);
}
}
Step 5: Run the application through maven or directly through intellij
# To run through maven, we will be using maven wrapper
# Navigate to the project directory and run the below command
./mvnw spring-boot:run
Once, the application is up we can access graphiql, which is provided by spring in order to use and build graphql queries
The UI can be accessed through the url http://localhost:8080/graphiql
Step 6: Play around and explore
Let us first create a few users using the createUser Mutation
# Create user test1
mutation MyMutation1 {
createUser(
email: "[email protected]"
name: "test1"
address: "test"
age: 10
phoneNumber: "9876543210"
) {
address
age
createdDate
email
name
id
phoneNumber
}
}
Similarly create a few test users
# Create user test2
mutation MyMutation2 {
createUser(
email: "[email protected]"
name: "test2"
address: "test"
age: 10
phoneNumber: "9876543210"
) {
address
age
createdDate
email
name
id
phoneNumber
}
}
# Create user test3
mutation MyMutation3 {
createUser(
email: "[email protected]"
name: "test3"
address: "test"
age: 10
phoneNumber: "9876543210"
) {
address
age
createdDate
email
name
id
phoneNumber
}
}
# Create user test4
mutation MyMutation4 {
createUser(
email: "[email protected]"
name: "test4"
address: "test"
age: 10
phoneNumber: "9876543210"
) {
address
age
createdDate
email
name
id
phoneNumber
}
}
# Create user test5
mutation MyMutation5 {
createUser(
email: "[email protected]"
name: "test5"
address: "test"
age: 10
phoneNumber: "9876543210"
) {
address
age
createdDate
email
name
id
phoneNumber
}
}
Once these users are created, we can now explore queries to fetch the created data
# The query below fetches three results
# 1. The hello string that we have hardcoded
# 2. Fetch id, name and email of user whose id is 1
# 3. Fetch addresses of all users
query MyQuery {
hello
getUser(id: "1") {
id
name
email
}
getAllUsers {
address
}
}
Similarly, updateUser and deleteUser mutations can be used
# Update address of user whose id is 5 to "updatedAddress"
mutation MyMutation {
updateUser(id: "5", address: "updatedAddress") {
address
age
createdDate
email
id
name
phoneNumber
}
}
# Delete user whose id is 5
mutation MyMutation {
deleteUser(id: "5")
}
# Fetch All User ids
query MyQuery {
getAllUsers {
id
}
}
Congratulations!!! You have now successfully created a GraphQL service with Spring Boot. In the upcoming parts of this tutorial we’ll explore more advanced topics in depth.