Resolvers and the N+1 problem
GraphQL makes N+1 easier to cause than REST did - and DataLoader is the standard fix.
Open this lesson in the learning hubKey points
- Each field has a resolver: a function returning that field’s value.
- A nested field resolves once per parent object, which is where N+1 appears.
- Ask for 50 orders each with a customer, and a naive resolver runs 1 + 50 queries.
- The client cannot see this - one innocent-looking query can hammer your database.
- DataLoader batches the per-item calls within one tick and caches within the request.
Example
// Naive: one query per order
@SchemaMapping(typeName = "Order")
public Customer customer(Order order) {
return repo.findById(order.customerId()); // N times
}
// Batched: one query for all of them
@BatchMapping(typeName = "Order")
public Map<Order, Customer> customer(List<Order> orders) {
var ids = orders.stream().map(Order::customerId).toList();
var byId = repo.findAllById(ids).stream()
.collect(toMap(Customer::id, c -> c));
return orders.stream()
.collect(toMap(o -> o, o -> byId.get(o.customerId())));
}
Nested resolvers run per parent - assume N+1 by default and batch before you ship.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the GraphQL Course course, and every lesson in it is listed on the GraphQL Course contents page.