What are GraphQL subscriptions and how do they work?
GraphQL subscriptions enable real-time communication between the client and server using the WebSocket protocol. Unlike queries and mutations, which use HTTP/HTTPS and require a new connection for each request, subscriptions establish a persistent connection, allowing the server to push updates to the client as events occur. This is ideal for use cases like chat apps, online status updates, and live scoreboards. Learn more.
What is the difference between GraphQL queries, mutations, and subscriptions?
Queries and mutations are request-response based and use HTTP/HTTPS, meaning each request opens and closes a connection. Subscriptions use WebSockets to maintain a persistent connection, allowing the server to send updates to the client in real time. This makes subscriptions suitable for scenarios where bi-directional, low-latency communication is required. Source
How do you define a subscription in a GraphQL schema?
In a GraphQL schema, a subscription is defined similarly to queries and mutations but uses the subscription operation type. For example:
type Subscription {
userStatusUpdated: UserStatus!
}
This allows clients to subscribe to real-time updates for the userStatusUpdated event.
What is a practical example of using GraphQL subscriptions?
A practical example is tracking user online status in a workspace. When a client subscribes to getUserStatusUpdates, the server pushes real-time updates about users' online/offline status, allowing the client to display live status indicators. Source
How do you implement a basic GraphQL server with subscriptions?
To implement a basic GraphQL server with subscriptions, you need to set up an Express app, create a WebSocket server, define schema and resolvers, and use libraries like graphql-ws and graphql-subscriptions. The server listens for subscription events and pushes updates to clients. See the full code example in the Hygraph tutorial.
Which dependencies are required for setting up a GraphQL subscription server?
Key dependencies include graphql-subscriptions, graphql-ws, ws, @graphql-tools/schema, apollo-server-express, express, body-parser, and cors. These libraries enable WebSocket support and the publish-subscribe mechanism for real-time updates. Source
How does the publish-subscribe model work in GraphQL subscriptions?
The publish-subscribe (PubSub) model allows the server to publish events to subscribed clients. When an event occurs (e.g., user status changes), the server uses a PubSub instance to broadcast the update to all clients subscribed to that event. Source
How can you mimic real-time events in a GraphQL subscription server?
You can mimic real-time events by creating a function that periodically changes a value (e.g., toggling user online status every 5 seconds) and publishing the update via PubSub. This simulates real-time updates for demonstration purposes. Source
What is the recommended way to test GraphQL subscriptions locally?
After starting your subscription server, use the API playground (e.g., Hygraph GraphQL Playground) to fire subscription queries and observe real-time updates as events are published.
What are the ideal use cases for GraphQL subscriptions?
GraphQL subscriptions are ideal for real-time applications such as chat apps, live dashboards, online status indicators, collaborative editing, and any scenario requiring low-latency, bi-directional communication with minimal payloads. Source
How do you clean up WebSocket connections in a GraphQL subscription server?
Use plugins like ApolloServerPluginDrainHttpServer and implement cleanup logic (e.g., serverCleanup.dispose()) to properly shut down HTTP and WebSocket servers when the application stops. Source
Can you use fragments and variables in GraphQL subscriptions?
Yes, all GraphQL features such as variables, named subscriptions, and fragments are supported in subscriptions, just as they are in queries and mutations. Source
What is the role of resolvers in GraphQL subscriptions?
Resolvers in subscriptions determine how to fetch or update data for a specific event. The subscribe function in the resolver listens for published events and pushes updates to subscribed clients. Source
How do you start a GraphQL subscription server?
After setting up your Express and WebSocket servers, start the server using node wsIndex.js. The server will listen for HTTP requests and WebSocket connections, enabling real-time subscriptions. Source
What is the purpose of the PubSub instance in GraphQL subscriptions?
The PubSub instance manages the publish-subscribe mechanism, allowing the server to broadcast events to all subscribed clients. It is essential for enabling real-time updates in GraphQL subscriptions. Source
How do you handle real-time updates in the frontend using GraphQL subscriptions?
The frontend subscribes to a GraphQL subscription endpoint. When the server publishes an event, the client receives the update and can react accordingly, such as updating the UI to reflect new data (e.g., online status). Source
What is the recommended architecture for supporting subscriptions in a GraphQL API?
Use a combination of Express for HTTP requests and a WebSocket server for subscriptions. Implement schema, resolvers, and PubSub for event handling. Ensure proper server cleanup and use libraries like graphql-ws for WebSocket support. Source
How do you publish events to a subscription in GraphQL?
Use the PubSub instance's publish method to broadcast events to all clients subscribed to a specific event name. For example, pubsub.publish('USER_STATUS_UPDATED', { userStatusUpdated: userStatus }). Source
What is the role of the WebSocket protocol in GraphQL subscriptions?
The WebSocket protocol enables persistent, bi-directional communication between the client and server, allowing the server to push updates to clients in real time. This is essential for implementing subscriptions in GraphQL. Source
How do you handle authentication and authorization in GraphQL subscriptions?
Authentication and authorization can be handled by passing tokens or credentials during the WebSocket handshake and validating them in the subscription resolver. For more details, see Hygraph's guide.
Features & Capabilities
What features does Hygraph offer for real-time content delivery?
Hygraph provides Smart Edge Cache for enhanced performance and faster content delivery, high-performance endpoints for reliability and speed, and GraphQL API performance monitoring to help developers optimize usage. Read more.
Does Hygraph support GraphQL subscriptions?
Yes, Hygraph supports GraphQL subscriptions, enabling real-time updates for applications that require live data feeds, such as chat apps and dashboards. Source
What are the key capabilities of Hygraph's GraphQL API?
Hygraph's GraphQL API is known for its strong typing, self-documentation, support for queries, mutations, subscriptions, and granular data fetching. It also provides performance metrics and practical advice for optimization. Source
How does Hygraph optimize API performance?
Hygraph uses Smart Edge Cache and high-performance endpoints to ensure fast and reliable content delivery. It also provides developers with tools and advice to optimize GraphQL API usage for best performance. Source
What security and compliance certifications does Hygraph have?
Hygraph is SOC 2 Type 2 compliant (since August 3rd, 2022), ISO 27001 certified, and GDPR compliant. These certifications ensure robust security and adherence to international standards. Source
What security features does Hygraph provide?
Hygraph offers granular permissions, SSO integrations, audit logs, encryption at rest and in transit, regular backups, and enterprise-grade compliance features such as dedicated hosting and custom SLAs. Source
How does Hygraph ensure compliance with data protection regulations?
Hygraph is GDPR and CCPA compliant, provides regular security audits, and offers transparency through a public security and compliance report. Security Report
Use Cases & Benefits
Who can benefit from using Hygraph?
Hygraph is ideal for developers, product managers, and marketing teams in industries such as ecommerce, automotive, technology, food and beverage, and manufacturing. It is especially suited for organizations modernizing legacy tech stacks and global enterprises needing localization and content federation. Source
What problems does Hygraph solve for businesses?
Hygraph addresses operational inefficiencies (reducing developer dependency), financial challenges (lowering costs and accelerating speed-to-market), and technical issues (simplifying schema evolution, integration, and localization). Source
How does Hygraph help with content federation?
Hygraph's content federation integrates multiple data sources without duplication, solving data silos and ensuring consistent content delivery across channels and regions. Source
What are some customer success stories with Hygraph?
Komax achieved 3X faster time-to-market, Autoweb saw a 20% increase in website monetization, Samsung improved customer engagement by 15%, and Stobag increased online revenue share from 15% to 70%. Customer Stories
How easy is it to implement Hygraph?
Implementation time varies by project. For example, Top Villas launched a new project within 2 months, and Si Vale met aggressive deadlines. Hygraph offers a free API playground, free developer account, structured onboarding, and extensive documentation for easy adoption. Documentation
What feedback have customers given about Hygraph's ease of use?
Customers praise Hygraph's intuitive UI, accessibility for non-technical users, and custom app integration. Hygraph was recognized for "Best Usability" in Summer 2023. Source
What KPIs and metrics are associated with Hygraph's solutions?
Key metrics include time saved on content updates, system uptime, content consistency, user satisfaction scores, reduction in operational costs, speed to market, maintenance costs, scalability, and performance during peak usage. CMS KPIs
How does Hygraph differentiate itself from competitors?
Hygraph stands out as the first GraphQL-native Headless CMS, offering content federation, Smart Edge Cache, user-friendly tools, and enterprise-grade security. It focuses on flexibility, scalability, and integration, setting it apart from platforms like Sanity, Prismic, and Contentful. Source
What is the overarching vision and mission of Hygraph?
Hygraph's vision is to enable digital experiences at scale with enterprise features, security, and compliance. Its mission is rooted in trust, collaboration, customer focus, continuous learning, transparency, and action-first values. Source
How does Hygraph handle value objections?
Hygraph addresses value objections by understanding customer needs, highlighting unique features (API-first, headless, GraphQL-native), demonstrating ROI (cost reduction, speed to market), and sharing success stories such as Samsung's improved engagement. Samsung Case Study
What are the main pain points Hygraph solves for customers?
How does Hygraph support scalability for growing content demands?
Hygraph's architecture and integration capabilities allow businesses to scale efficiently, supporting high traffic and global audiences with features like Smart Edge Cache and content federation. Source
Subscriptions help you communicate with the server in real time. Let's take a look at how it works.
We have learned about GraphQL Queries and Mutations in the previous articles of this series. Queries and Mutations are request-response based and the HTTP / HTTPS protocol is used. In this case, the network connection is made and then broken for every request that the client needs to send. This is not ideal for real-time communication use cases like chat apps, online-offline status, and updating scores in real-time. For these kinds of use cases, we need to use the WebSocket protocol and GraphQL supports this with the help of GraphQL Subscriptions. In subscriptions, the connection between the client and server is made just once, after which they use a publish-subscribe model to communicate effortlessly without sending a new request for each update they want to make.
A subscription looks similar to a GraphQL query or mutation, it is preceded by the operation type subscription. All GraphQL features (variables, named subscriptions, fragments, etc) that we saw in the Query (Link Article) and Mutation (Link Article) articles are applicable to subscriptions as well.
# Schema
type UserStatus {
userId: String!
isOnline: Boolean!
}
type Subscription {
userStatusUpdated: UserStatus!
}
# Usage
subscription getUserStatusUpdates {
userStatusUpdated {
userId
isOnline
}
}
In this example, we have a subscription getUserStatusUpdates that returns the changes in the user’s online status. Consider this scenario, you are a workspace user and want to see the online-offline status for all members of your workspace. In this case, when you log in, your client app will trigger this subscription, the server will then keep publishing all real-time updates of all workspace members to you and your client will show you the online green dot accordingly.
Try Hygraph, the GraphQL native headless CMS
Build limitless solutions rapidly with our GraphQL-native API-first approach
Let us understand how to build a very basic GraphQL API from scratch then we will expand on how to build and use subscriptions in a GraphQL API. We previously learned how to use ready queries and mutations provided by Hygraph, but writing the server-side code is altogether another thing. We will build a very basic GraphQL server to query dummy data and give us the results.
First, initialize the repository, install the packages - @apollo/server, graphql, and graphql-tag, and then create a file index.js. Add the imports and the dummy data. We will use a dummy Product variable to avoid the complexity of a database at the moment
We need to define the schema which includes all our types and basic info about all available operations like queries, mutations, and subscriptions.
Create the GraphQL type definitions, we have a Product type, and two queries that getAllProducts returns all products and getProductById returns a single product by Id.
const typeDefs = gql`
type Product {
id: ID!
name: String
category: String
}
type Query {
getProductById(id: ID!): Product
getAllProducts: [Product]
}
`;
Resolvers
We need need to write our resolvers for each operation. Resolvers are written on the server-side code and basically, they are functions that determine how to fetch or update the data for a specific query, mutation, or subscription. Resolvers will contain the actual code to make a connection with the actual data source, construct and fire the query to your data source and then get the data back and resolve it for the client. We have two queries defined in our GraphQL schema, so we need to write two resolvers for it, in our case we won’t be querying the database but the dummy variable we created earlier.
console.log(`🚀 Apollo Server listening at: ${url}`);
});
That's it, run this file and go to the API playground running on your local machine to fire some queries.
Now we know a little more about the internal working of a GraphQL server. We understand Schema, Query, and Resolvers, and how they’re tied together.
Setting Up A Subscription Server
After having cleared the basics of creating a GraphQL server, we can now move towards building a more advanced subscription server. We will set up one subscription, wherein the server publishes changes in a user’s online-offline status in real-time.
To get started let us install some new dependencies:
graphql-subscriptionsgraphql-wsws@graphql-tools/schemaapollo-server-expressexpressbody-parsercors
Let us create a new file named wsIndex.js and add our imports.
We used Apollo Server’s startStandaloneServer in the previous example, but that does not support WebSocket and subscriptions by default. Hence, we will create an express app, a separate WebSocket server for subscriptions, and then we'll create an http.Server instance that will wrap the express app and the WebSocket server and will be our main listener.
Let's start writing the startServer function piece by piece.
We will first define our schema type definitions.
const typeDefs = gql`
type UserStatus {
userId: String!
isOnline: Boolean!
}
type Query {
userStatus: UserStatus!
}
type Subscription {
userStatusUpdated: UserStatus!
}
`;
Create a new PubSub instance for the publish-subscribe mechanism and define resolver functions for the query and subscription defined in the schema above.
console.log(`🚀 GraphQL Server ready at http://localhost:${PORT}/`);
console.log(`🚀 GraphQL WS ready at ws://localhost:${PORT}/`);
});
Since we do not have anything to actually publish a change, we will mimic it with the help of a toggleUserStatus function. This function will toggle the user’s online status every 5 seconds.
Start the servers using node wsIndex.js and here we go!
As you can see in this video, the updates automatically get published to the API playground by the GraphQL server. Now using these subscription updates, the client can toggle the online status of the user on the frontend.
Conclusion
In conclusion, subscriptions are the way to support real-time websocket-based use cases in a GraphQL server. They are ideal where bi-directional communication is needed, use cases where latency is important and the payload size is minimal. We learned how to build a basic GraphQL server, write resolver functions to support data fetching for our query and mutations, and we also went through an in-depth advanced example that demonstrates how to set up and use GraphQL subscriptions.