How to make GraphQL subscriptions form a React Component
This article is part of a series of six articles using React with the Apollo Client.
As a custom React component developer, you want to use GraphQL to subscribe to events emitted from the backend, respond to those events and take action on the front end.
Without complex logic, I want to update active queries automatically to re-render the data in components and ensure the cache is not stale.
What are subscriptions?
Like queries, subscriptions enable you to fetch data. Unlike queries, subscriptions are long-lasting operations that can change their result over time. They can maintain an active connection to your GraphQL server (most commonly via WebSocket), enabling the server to push updates to the subscription’s result.
What are active queries?
Active Queries” are queries running in mounted components, Apollo uses active queries to update results when cache is updated.
This example is for a “generic” React application with deliberately verbose code.
The Solution
Apollo provides a React hook: useSubscription
The hook is similar to useQuery
and useMutation
, encapsulating the complex subscription and result logic.
The solution uses:
- Apollo Client instance — a single instance shared between ALL components
- Subscription definition — complied into AST exactly once
- Code generation for TypeScript — for type-safe queries
- Subscriptions — Container within two functional components that subscribe to the events using
useSubscription
Apollo hook and display Notifications. - Watching for results — rendered in React and refreshed the cache via
active queries
Subscription definition and compilation
A best practice is to define and compile subscriptions and “compile” them exactly once.
In the front-end project, create a directory to contain subscription definitions; this can be the same file as Queries and Mutations. In this example, the directory graphql
is a subdirectory under src,
and it contains query, mutation and subscription definitions and types.ts
generated from the schema (more on this later).
Here, each file is contributed by the domain or bounded context. Each operation in the file is compiled into an AST and stored in a public constant. Compilation is done only once when the file is loaded.
Lines 5–22 define the Subscription operations: LINEITEM_ACTIVATED
and LINEITEM_PAUSED
Super Important — Each Subscription should be named
Both these subscriptions are similar (deliberately), and LineitemPaused
will be discussed further.
Line 16 is the subscription operation LineitemPaused
with the parameter $lineitemId
used to qualify (or filter) the specific event subscribed on the server.
Notification Components
Two functional components LineitemPaused
and LineitemActivated
encapsulate the Subscription and display a notification to the user. This example is for the LineitemPaused
subscription.
Lines 3–8 subscribe for the LINEITEM_PAUSED
subscription with the useSubscription
hook. Note that the subscription takes the lineitemId as a parameter; this ensures that the events are qualified (filters) on the server.
Line 3 the useSubscription
hook is qualified by the types LineitemPausedSubscription
and LineitemPausedSubscriptionParameters
. These types prescribe the shape of the event and the parameters.
These types are generated from GraphQL subscription definitions (see above) using:
No complex cache refresh, re-query, or rerender logic is needed. The ApolloClient and the Apollo React hooks handle these functions.
Conclusion
GraphQL in React is made easy by using @apollo/client
Subscriptions and their results are integrated with React’s component rendering and hooks for a seamless user experience.