Problem
Similar to REST, with GraphQL we can query data from server/backend and also update data. These are Query and Mutation in GraphQL. But what if clients want to get pushed updates from the server when data they care about changes?
Solution
Subscriptions are similar to queries in that they specify a set of fields to be delivered to the client, but instead of immediately returning a single answer, a result is sent every time a particular event happens on the server. In the code below, a persistent WebSocket connection gets established at the beginning and used across the lifecycle until client wants to consume messages or until server is available.
Example
Here is a subscription example with Spring Boot. GraphQL Spring Boot starter will read the Schema definition file and configure it.
spring.graphql.websocket.path=/graphql
spring.graphql.graphiql.enabled=true
Here's the application.properties file.
public record StockPrice(String symbol, double price, LocalDateTime timestamp) {}
StockPrice record is intended for data transfer.
type Query {
hello: String
}
type Subscription {
stockPrice(symbol: String): StockPrice
}
type StockPrice {
symbol: String
price: String
timestamp: String
}
@Controller
public class RequestHandler {
new *
@SubscriptionMapping("stockPrice")
public Flux<StockPrice> stockPrice(@Argument String symbol) {
Random random = new Random();
return Flux.interval(Duration.ofSeconds (1))
.map (num -> new StockPrice (symbol,
random. nextDouble(), LocalDateTime.now()));
}
}
RequestHandler class with stockPrice method (matching to the GraphQL Schema Definition Language) is for using subscription type. This method will be invoked by running the subscription query.
subscription {
stockPrice(symbol: "ABC") {
symbol
price
timestamp
}
}
{
"data": {
"stockPrice": {
"symbol" : "ABC",
"price": "0.42954546659309123",
"timestamp": "2023-05-17T13:18:25.625699"
}
}
}
At first in the output there will be this sentence: "Your subscription data will appear here after server publication!" which will change after receiving result from the server.