Complete Guide to GraphQL with Java (Spring Boot) – From Zero to Hero 🚀
GraphQL is a powerful alternative to REST APIs, providing flexible, efficient data fetching. In this guide, I will explain why each concept exists and how it works, assuming you know nothing about GraphQL.
By the end, you’ll be able to build a fully functional GraphQL API in Java Spring Boot with queries, mutations, subscriptions, and security.
1. What is GraphQL and Why Do We Need It?
Imagine you are building an app that fetches user data from an API. With a traditional REST API, you might have endpoints like:
GET /users/1→ Returns all user details (even if you need only the name).GET /users/1/posts→ Fetches posts separately, needing another request.
The problems?
- Over-fetching – You get extra data that you don’t need.
- Under-fetching – You need multiple API calls to get related data.
How GraphQL Solves These Issues
- You send one request and get exactly what you need.
- You can fetch related data in a single request.
2. GraphQL vs REST – Which is Better?
| Feature | GraphQL | REST |
|---|---|---|
| Data Fetching | Select specific fields | Returns the full response |
| Number of Endpoints | Single endpoint (/graphql) |
Multiple endpoints (/users, /posts) |
| Over-fetching | ❌ No (only requested fields) | ✅ Yes (extra data is returned) |
| Under-fetching | ❌ No (fetch related data in one call) | ✅ Yes (multiple requests needed) |
| API Evolution | Schema-based (no versioning) | Versioned (/v1/users, /v2/users) |
3. Installing GraphQL in Java Spring Boot
Since GraphQL is just a query language, it needs to be implemented in a backend framework. We’ll use Spring Boot because it provides:
- Easy integration with GraphQL.
- Built-in support for database interactions.
Step 1: Add Dependencies
We need the following dependencies in pom.xml:
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>11.1.0</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>5.2.4</version>
</dependency>
Now, we can start defining our GraphQL schema.
4. GraphQL Schema – The Heart of GraphQL
Unlike REST APIs, where endpoints define responses, GraphQL uses a schema to define:
- Data types (objects in the system).
- Queries (how to fetch data).
- Mutations (how to modify data).
Example Schema (schema.graphqls)
type User {
id: ID!
name: String!
email: String!
}
type Query {
getUser(id: ID!): User
getAllUsers: [User]
}
type Mutation {
createUser(name: String!, email: String!): User
deleteUser(id: ID!): Boolean
}
💡 Why do we need this schema?
This schema acts as a contract between the client and server, ensuring structured data exchange.
5. Implementing GraphQL API in Java Spring Boot
Step 1: Define the Entity
GraphQL will interact with a database, so let’s define an entity.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// Constructors, Getters, and Setters
}
💡 Why do we need an entity?
Entities represent database tables. Each instance corresponds to a row.
Step 2: Create the Repository
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
💡 Why use a repository?
The repository allows us to interact with the database without writing SQL.
Step 3: Create the GraphQL Service
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
public List<User> getAllUsers() {
return userRepository.findAll();
}
public User createUser(String name, String email) {
User user = new User();
user.setName(name);
user.setEmail(email);
return userRepository.save(user);
}
public boolean deleteUser(Long id) {
if (userRepository.existsById(id)) {
userRepository.deleteById(id);
return true;
}
return false;
}
}
💡 Why use a service layer?
The service layer separates business logic from the GraphQL resolvers.
Step 4: Implement GraphQL Query Resolver
@Component
public class UserQueryResolver implements GraphQLQueryResolver {
private final UserService userService;
public UserQueryResolver(UserService userService) {
this.userService = userService;
}
public User getUser(Long id) {
return userService.getUserById(id);
}
public List<User> getAllUsers() {
return userService.getAllUsers();
}
}
💡 Why use resolvers?
Resolvers tell GraphQL how to fetch data.
Step 5: Implement GraphQL Mutation Resolver
@Component
public class UserMutationResolver implements GraphQLMutationResolver {
private final UserService userService;
public UserMutationResolver(UserService userService) {
this.userService = userService;
}
public User createUser(String name, String email) {
return userService.createUser(name, email);
}
public boolean deleteUser(Long id) {
return userService.deleteUser(id);
}
}
💡 Why separate queries and mutations?
This follows GraphQL’s best practices for clarity and maintainability.
6. Querying Data in GraphQL
Let’s test our API!
Fetching a Single User
GraphQL Query:
{
getUser(id: 1) {
name
email
}
}
💡 Why use queries?
Queries allow us to fetch data efficiently.
7. Mutations – Modifying Data
Creating a User
GraphQL Mutation:
mutation {
createUser(name: "Alice", email: "alice@example.com") {
id
name
email
}
}
💡 Why use mutations?
Mutations allow clients to modify server-side data.
8. Subscriptions – Real-Time Updates
GraphQL supports real-time updates using subscriptions.
Example Subscription
type Subscription {
userCreated: User
}
💡 Why use subscriptions?
Subscriptions push data updates instead of clients polling.
9. Securing GraphQL API
To prevent unauthorized access, we use Spring Security.
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
}
}
💡 Why secure GraphQL APIs?
Since GraphQL has one endpoint, it needs role-based access control.
10. GraphQL Tools for Development
- GraphiQL – In-browser IDE to test queries.
- Postman – Supports GraphQL requests.
- Apollo Client – Frontend GraphQL client.
11. Error Handling in GraphQL
GraphQL provides structured error responses.
Handling Errors in Java
@ControllerAdvice
public class GraphQLExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<GraphQLError> handleException(RuntimeException ex) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new GraphQLError(ex.getMessage()));
}
}
Resources
Here are some valuable resources to help you deepen your understanding of GraphQL, especially in the context of Java and Spring Boot:
- Official GraphQL Documentation: Provides a comprehensive overview of GraphQL concepts, syntax, and best practices.
- Spring for GraphQL Documentation: Detailed guide on integrating GraphQL with Spring applications, including setup and configuration.
- GraphQL Java Documentation: Covers the GraphQL Java implementation, offering insights into its usage and features.
- Spring’s Official Guide on Building a GraphQL Service: A step-by-step tutorial on creating a GraphQL service using Spring Boot.
- “How to GraphQL” Fullstack Tutorial: An in-depth tutorial that covers GraphQL concepts and implementations across various stacks, including Java.
- Baeldung’s Guide to Spring GraphQL: An article that explains setting up a GraphQL server using Spring Boot, with practical examples.
- GraphQL Java Kickstart’s Spring Boot Tutorial: A concise tutorial on creating a GraphQL server with Spring Boot in a few minutes.
- YouTube Tutorial: Spring Boot and GraphQL Tutorial: A video tutorial that walks through building a GraphQL API using Spring Boot.
- YouTube Playlist: Spring Boot GraphQL Tutorial - Full Course: A comprehensive video series covering various aspects of integrating GraphQL with Spring Boot.
- Auth0’s Guide on Building a GraphQL API with Spring Boot: A step-by-step guide demonstrating how to build a secured GraphQL API with Spring Boot.