Spring for GraphQL simplifies the development of GraphQL APIs by integrating with Spring Boot. This guide demonstrates how to create a GraphQL API using Java and Kotlin, with examples for schema definition, query handling, and dependency injection.
Written by
Şuayb Şimşek
Backend-focused fullstack developer sharing practical notes on Spring Boot, security, microservices, and cloud-native architecture.
Get practical backend + fullstack notes when new articles are published.
Social
🌟 Why Use GraphQL?
GraphQL allows clients to request specific data, reducing over-fetching and under-fetching compared to REST. It also supports strong typing and facilitates efficient data fetching, making it a popular choice for modern APIs.
📋 Prerequisites
📋 Ensure you have the following:
☕ Java Development Kit (JDK) 17+
📦 Maven or Gradle installed
🔤 A Java IDE (e.g., IntelliJ IDEA, Eclipse)
🛠️ Step 1: Add Dependencies
Include the following dependencies in your project to enable Spring for GraphQL.
Create a schema file named schema.graphqls under the src/main/resources/graphql directory.
GRAPHQLschema.graphqls
type Query {
getUser(id: ID!): User
getUsers: [User]
}
type User {
id: ID!
name: String!
email: String!
}
🛠️ Step 3: Implement the Data Model and Services
Define the data model and service layer for handling queries.
🛠️ Step 4: Implement GraphQL Controllers
Controllers handle GraphQL queries and mutations. Use the @Controller annotation in Spring for GraphQL.
▶️ Running the Application
Run the application using the following commands:
Spring Boot (Java/Kotlin):
Run the application with either stack to confirm the baseline setup is working before deeper tests.
BASH
./mvnw spring-boot:run
Access the GraphQL Playground at http://localhost:8080/graphiql to test your API.
🧪 Testing the GraphQL API
Here are some example queries to test your API:
Fetch a user by ID:
GRAPHQLquery.graphql
query {
getUser(id: "1") {
id
name
email
}
}
Fetch all users:
GRAPHQLquery.graphql
query {
getUsers {
id
name
email
}
}
🏁 Conclusion
You now have a practical Building APIs with Spring for GraphQL implementation with a clear, production-friendly Spring Boot structure. As a next step, adapt configuration and tests to your own domain, then validate behavior under realistic traffic and failure scenarios.
Entity
JAVAUser.java
package com.example.demo.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private String id;
private String name;
private String email;
}
Service
JAVAUserService.java
package com.example.demo.service;
import com.example.demo.model.User;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
public class UserService {
private final Map<String, User> userData = Stream.of(
new User("1", "Alice", "alice@example.com"),
new User("2", "Bob", "bob@example.com")
).collect(Collectors.toMap(User::getId, user -> user));
public User getUser(String id) {
return userData.get(id);
}
public List<User> getUsers() {
return List.copyOf(userData.values());
}
}
Entity
KOTLINUser.kt
package com.example.demo.model
data class User(
val id: String,
val name: String,
val email: String
)
Service
KOTLINUserService.kt
package com.example.demo.service
import com.example.demo.model.User
import org.springframework.stereotype.Service
@Service
class UserService {
private val userData = mapOf(
"1" to User("1", "Alice", "alice@example.com"),
"2" to User("2", "Bob", "bob@example.com")
)
fun getUser(id: String): User? = userData[id]
fun getUsers(): List<User> = userData.values.toList()
}
JAVAUserController.java
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
import java.util.List;
@Controller
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@QueryMapping
public User getUser(String id) {
return userService.getUser(id);
}
@QueryMapping
public List<User> getUsers() {
return userService.getUsers();
}
}
KOTLINUserController.kt
package com.example.demo.controller
import com.example.demo.model.User
import com.example.demo.service.UserService
import org.springframework.graphql.data.method.annotation.QueryMapping
import org.springframework.stereotype.Controller
@Controller
class UserController(
private val userService: UserService
) {
@QueryMapping
fun getUser(id: String): User? = userService.getUser(id)
@QueryMapping
fun getUsers(): List<User> = userService.getUsers()
}