Implementing Batching and Caching
Integrate DataLoaders into your Spring Boot resolvers to optimize data retrieval and reduce database roundtrips.
DataLoaders: Time to Implement!
Welcome back! In previous lessons, we learned about the N+1 problem and how DataLoaders provide an elegant solution through batching and caching.
Today, we'll get hands-on and integrate DataLoaders into a Spring Boot GraphQL application. We'll see how to define a BatchLoader, register it, and use it in our GraphQL resolvers.
Simulating a Data Service
First, let's set up a simple mock service that simulates fetching users from a database. This service will be called by our DataLoaders.
Notice the System.out.println, which will help us observe when the actual 'database' call happens, demonstrating batching later.
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
// A simple User data class
class User {
String id;
String name;
User(String id, String name) {
this.id = id; this.name = name;
}
public String getId() { return id; }
public String getName() { return name; }
}
// Mock service to fetch users (simulates DB call)
class MockUserService {
private final Map<String, User> users = Map.of(
"1", new User("1", "Alice"),
"2", new User("2", "Bob"),
"3", new User("3", "Charlie"),
"4", new User("4", "David")
);
public List<User> findAllByIds(List<String> ids) {
System.out.println("DB Call: Fetching users for IDs: " + ids);
return ids.stream()
.map(users::get)
.filter(user -> user != null)
.collect(Collectors.toList());
}
}
public class Main {
public static void main(String[] args) {
MockUserService service = new MockUserService();
List<User> foundUsers = service.findAllByIds(List.of("1", "3"));
System.out.println("Found: " + foundUsers.size() + " users.");
}
}All lessons in this course
- The N+1 Problem Explained
- Introducing GraphQL DataLoaders
- Implementing Batching and Caching
- DataLoaders with Spring Context and Async