Subscriptions
Queries are useful to fetch data from a server. Mutations are useful to modify data. Subscriptions allow to listen to data changes comming from a server. They work by opening a channel with the server and receiving updates as they are pushed by the server, usually using a websocket.
Subscriptions are similar to queries in syntax, the only difference being that you use the keyword subscription
instead of query
to indicate that the root fields on this query are going to be performing writes to the backend.
Configuring the network transport
Since they're typically not using HTTP, you will need to customize the NetworkTransport
used for subscriptions. For this, Apollo Android comes with WebSocketNetworkTransport
:
val apolloClient = ApolloClient(
networkTransport = WebSocketNetworkTransport(
serverUrl = "https://apollo-fullstack-tutorial.herokuapp.com/graphql"
)
)
WebSocketNetworkTransport
makes it easy to customize the protocol for different backends through the WsProtocol
interface. There is builtin support for AppSync with AppSyncWsProtocol
and graphql-ws GraphQLWsProtocol
. For an example, configure a graphql-ws
transport with:
val apolloClient = ApolloClient(
networkTransport = WebSocketNetworkTransport(
serverUrl = "http://localhost:9090/graphql",
protocol = GraphQLWsProtocol()
)
)
Listening to a subscription
Once you have configured the NetworkTransport
, use ApolloClient.subscribe
to open the connection and listen to changes:
apolloClient.subscribe(TripsBookedSubscription())
.collect {
println("trips booked: ${it.data?.tripsBooked}")
}
Because subscriptions are long running operations, they return a Flow<Response>
instead of a single Response
.
Cancellation is handled through the coroutine scope. Cancel the coroutine to stop the subscription.
Like for queries, partial responses are supported and will be emitted in the Flow
. Transport errors will terminate the Flow
and you will have to retry it to get new updates. Retrying may reopen a new WebSocket or restart the subscription dependending the cases.
By default, a single WebSocket is shared between all the subscriptions. When no subscription is active, the WebSocket will be closed after a configurable timeout.