GraphQL as an API Layer
AdvancedGraphQL aggregates data from multiple microservices in a single query, reducing over-fetching and under-fetching; ideal for flexible client-driven data requirements.
Overview
In a microservices architecture, GraphQL is often placed at the API gateway layer as a federated aggregation point. Instead of clients making multiple REST calls to different services (order service, customer service, product service) and stitching data together, a single GraphQL query traverses resolvers that fan out to the appropriate downstream services. Spring for GraphQL (spring-boot-starter-graphql) provides schema-first development with annotated controllers, DataLoader integration for batching/caching, and subscriptions over WebSocket. Apollo Federation takes this further by letting each microservice own part of the schema, which the gateway then composes into a unified supergraph.
Spring for GraphQL — Schema and Controller
Define the schema in .graphqls files under src/main/resources/graphql/. Map query fields to @QueryMapping methods; use @SchemaMapping for nested type resolvers that call downstream services.
# schema.graphqls
type Query {
order(id: ID!): Order
}
type Order {
id: ID!
status: String!
customer: Customer # resolved by CustomerService
items: [OrderItem!]! # resolved by ProductService
}
@Controller
public class OrderController {
@QueryMapping
public Order order(@Argument Long id) {
return orderService.findById(id);
}
@SchemaMapping(typeName = "Order", field = "customer")
public Customer customer(Order order) {
return customerClient.findById(order.getCustomerId()); // HTTP / gRPC call
}
}DataLoader — Solving N+1
When a list of orders each resolves a customer, the naive approach makes N HTTP calls. DataLoader batches all keys collected during a single execution tick into one call, then caches results within the request.
@Component
public class CustomerDataLoader implements BatchLoaderWithContext<Long, Customer> {
@Override
public CompletionStage<List<Customer>> load(List<Long> ids, BatchLoaderEnvironment env) {
return CompletableFuture.supplyAsync(() ->
customerClient.findAllByIds(ids)); // single batch call
}
}
// In resolver — DataLoader is auto-registered by Spring for GraphQL
@SchemaMapping(typeName = "Order", field = "customer")
public CompletableFuture<Customer> customer(Order order, DataLoader<Long, Customer> loader) {
return loader.load(order.getCustomerId()); // batched automatically
}Apollo Federation — Distributed Schema
With Apollo Federation each service defines its own partial schema and implements a reference resolver. The Apollo Router (or Gateway) stitches subgraphs into a unified API. Services extend types owned by other services using @key and @extends.
# order-service subgraph schema
type Order @key(fields: "id") {
id: ID!
status: String!
customerId: ID!
}
# customer-service subgraph extends Order
extend type Order @key(fields: "id") {
id: ID! @external
customer: Customer @requires(fields: "customerId")
}
# The Apollo Router composes both into one supergraph:
# query { order(id: "1") { status customer { name email } } }Key Points to Remember
- 1GraphQL eliminates over-fetching (too many fields) and under-fetching (too many round trips)
- 2Spring for GraphQL uses annotated controllers + schema-first .graphqls files
- 3DataLoader batches N resolver calls into one bulk fetch to prevent the N+1 problem
- 4Subscriptions over WebSocket enable real-time data push from GraphQL resolvers
- 5Apollo Federation lets each microservice own its schema slice; the gateway composes them
- 6GraphQL is not always better than REST — use it when clients have highly variable data needs
Interview Questions
Sign in to ask AriaWhat is the N+1 problem in GraphQL and how does DataLoader solve it?
What is the difference between a Query, Mutation, and Subscription in GraphQL?
How does Apollo Federation distribute the GraphQL schema across microservices?
When would you choose GraphQL over REST for a microservices API layer?
How do @SchemaMapping and @QueryMapping differ in Spring for GraphQL?
Ask Aria about GraphQL as an API Layer
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.