Subscriptions
The third operation type: the server pushes to you, over a connection that stays open.
Open this lesson in the learning hubKey points
- A query and a mutation are request-response - you ask, the server answers, the connection is done. A subscription is a stream: you ask once, and the server sends an event every time something happens, for as long as you stay connected.
- It is declared like any other root type, under
type Subscription, and the client selects fields exactly as it would on a query. The selection set is applied to every event, so each client receives only the fields it asked for. - The transport is not plain HTTP. A subscription needs a connection that stays open, which in practice means a WebSocket - the
graphql-transport-wsprotocol is the current standard, and Spring for GraphQL speaks it. - Use it for things that genuinely arrive when the server decides: a live order status, a chat message, a build finishing. Do not use it as a substitute for polling something that changes on a schedule - a query on a timer is simpler and far cheaper to operate.
- Events are usually published by a mutation. Somebody places an order, the mutation writes it and publishes an event, and every subscriber selecting that order receives it. The two operation types work as a pair.
- One practical warning before you ship one: a subscription holds server memory for as long as the client is connected, and the cost is driven by how many clients exist rather than by how many requests they send. That changes how you size the service.
Example
type Subscription {
orderStatusChanged(orderId: ID!): Order!
}
# The client subscribes once ...
subscription WatchOrder($id: ID!) {
orderStatusChanged(orderId: $id) {
id
status # the selection is applied to EVERY event
updatedAt
}
}
# ... and receives a message each time it changes:
# { "data": { "orderStatusChanged": { "id": "42", "status": "PACKED", ... } } }
# { "data": { "orderStatusChanged": { "id": "42", "status": "SHIPPED", ... } } }
# { "data": { "orderStatusChanged": { "id": "42", "status": "DELIVERED", ... } } }
# Spring for GraphQL: return a Publisher and the framework does the rest.
# @SubscriptionMapping
# public Flux<Order> orderStatusChanged(@Argument String orderId) {
# return orderEvents.forOrder(orderId);
# }
Queries pull, subscriptions push - use them for events the server decides to send, and remember each one holds a connection open for as long as the client stays.
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.