Prepared Docs

Prepared Docs

⌘K

    Loading navigation…

User

  1. Working With Data
  2. Pub Sub

Pub/Sub

GraphQL subscriptions and real-time data.

Quick Reference

GraphQL subscriptions:

  • Use useSubscription hook from Apollo Client
  • Handle connection lifecycle (loading, error, data)
  • Clean up subscriptions on unmount
  • Combine with queries for initial data + live updates
  • A subscription result is written to the cache, so changed fields on an entity update every query that shows it; only list membership needs code (GraphQL Cache)

GraphQL Subscriptions

Use useSubscription for real-time data updates:

Query + Subscription Pattern

Combine initial query with subscription for updates:

Subscription with Cache Updates

A subscription that adds an entity to a list needs one cache update: Apollo writes the new message to the cache itself, but it can't know that the message belongs in Chatroom.messages. Add its reference to the list, and skip it when it's already there. The same message can also arrive from your own mutation or a refetch.

  • A list holds references ({ __ref: "Message:7" }), so compare ids with readField, not objects.
  • modify changes only a field that is already cached. If no query has fetched messages yet, there's nothing to update, and the query fetches the current list when it runs.
  • An update to an existing message (an edit, a read receipt) needs no cache code at all.

GraphQL Cache covers modify, updateQuery, eviction, and when refetchQueries is the better tool.

Conditional Subscriptions

Subscribe only when needed:

Error Handling

Show the user that live updates stopped, and don't report the error yourself. The shell's Apollo client reports a socket that closed for good once per subscription, and the backend has already reported an error it sent (Who reports an error).

Reconnection Handling

Handle connection drops gracefully:

Multiple Subscriptions

Testing Subscriptions

Render with renderWithApollo from @prepared911/util-testing, as for any Apollo test: queries go to the schema-driven MSW handlers, and the cache, masking, and links are the app's. The mock handlers answer HTTP requests, not WebSocket ones, so give the client a terminating link that sends subscriptions to a test-controlled source and everything else to MSW. Then push results from the test.

  • The pushed result is written to the cache like a real one, so the same test can render a query root and check that the subscription updated what the query showed. Pin the query's id with createPreparedMockHandlers({ mocks }) so both name the same entity.
  • push data includes __typename and id, like a server response; @prepared911/data-gql/factories builds whole objects.
  • Use findBy… after a push: components re-render on a later tick.

Related Documentation

  • GraphQL Operations - Query and mutation patterns
  • GraphQL Cache - Updating the cache from subscriptions and mutations
  • Writing Hooks - useEffect cleanup for subscriptions
  • State Management - Managing subscription data

Reference Files

For more detailed technical guidance, see these reference files:

  • effect-when-to-use.md - WebSocket/subscription patterns
  • effect-cleanup.md - Subscription cleanup

Previous

Working with data / GraphQL Overview

Next

Working with data / GraphQL Operations

On this page

Quick Reference
GraphQL Subscriptions
Query + Subscription Pattern
Subscription with Cache Updates
Conditional Subscriptions
Error Handling
Reconnection Handling
Multiple Subscriptions
Testing Subscriptions
Related Documentation
Reference Files