Frequently Asked Questions

GraphQL Subscriptions & Real-Time Features

What are GraphQL subscriptions and how do they work?

GraphQL subscriptions enable real-time, bi-directional communication between clients and servers. Unlike queries and mutations, which use HTTP/HTTPS and require a new connection for each request, subscriptions use the WebSocket protocol. This allows the client to establish a persistent connection and receive updates automatically whenever data changes on the server. Subscriptions are ideal for use cases like chat applications, online status indicators, and live score updates. (Source: Hygraph GraphQL Subscriptions Guide)

What is a typical use case for GraphQL subscriptions?

GraphQL subscriptions are commonly used for real-time features such as chat applications, tracking online/offline user status, and updating live scores. For example, a workspace app can use a subscription to display the online status of all members in real time, updating the UI automatically as users come online or go offline. (Source: Hygraph GraphQL Subscriptions Guide)

How do you implement GraphQL subscriptions in a server?

To implement GraphQL subscriptions, you need to set up a WebSocket server alongside your HTTP server. This typically involves using libraries such as graphql-ws, ws, and graphql-subscriptions. You define your subscription types in the schema, create a publish-subscribe mechanism (e.g., using PubSub), and write resolver functions for your subscriptions. The server then pushes updates to subscribed clients whenever relevant data changes. (Source: Hygraph GraphQL Subscriptions Guide)

What are the benefits of using GraphQL subscriptions over traditional request-response APIs?

GraphQL subscriptions provide real-time updates and reduce latency by maintaining a persistent connection between client and server. This is more efficient than traditional request-response APIs, which require repeated polling or manual refreshes. Subscriptions are ideal for scenarios where immediate feedback or live data is critical, such as collaborative tools, dashboards, or notification systems. (Source: Hygraph GraphQL Subscriptions Guide)

What protocols are used for GraphQL subscriptions?

GraphQL subscriptions use the WebSocket protocol to establish a persistent, bi-directional connection between the client and server. This allows for efficient real-time data transfer without the overhead of repeated HTTP requests. (Source: Hygraph GraphQL Subscriptions Guide)

Hygraph Platform Features & Capabilities

What features does Hygraph offer for developers and content teams?

Hygraph provides a GraphQL-native architecture, content federation, and scalability. It supports real-time content delivery, integrations with popular platforms (e.g., Netlify, Vercel, Shopify, AWS S3, Cloudinary), and offers an intuitive interface for both technical and non-technical users. Hygraph also includes robust security features, compliance certifications, and a wide range of documentation and onboarding resources. (Source: Hygraph Features)

Does Hygraph support GraphQL subscriptions?

Yes, Hygraph supports GraphQL subscriptions, enabling real-time updates and event-driven workflows for applications that require live data. (Source: Hygraph GraphQL Subscriptions Guide)

What integrations are available with Hygraph?

Hygraph offers integrations with hosting and deployment platforms (Netlify, Vercel), eCommerce solutions (BigCommerce, commercetools, Shopify), localization tools (Lokalise, Crowdin, EasyTranslate, Smartling), digital asset management (Aprimo, AWS S3, Bynder, Cloudinary, Mux, Scaleflex Filerobot), personalization and AB testing (Ninetailed), AI (AltText.ai), and more. (Source: Hygraph Integrations)

Does Hygraph provide an API for content management?

Yes, Hygraph provides a powerful GraphQL API that allows you to fetch and manage content efficiently. You can learn more about it at the Hygraph API Reference.

Security, Compliance & Performance

What security and compliance certifications does Hygraph have?

Hygraph is SOC 2 Type 2 compliant, ISO 27001 certified, and GDPR compliant. These certifications ensure enterprise-grade security and data protection for all users. (Source: Hygraph Security Features)

How does Hygraph ensure optimized content delivery performance?

Hygraph emphasizes optimized content delivery performance, which directly impacts user experience, engagement, and search engine rankings. By ensuring rapid content distribution and responsiveness, Hygraph helps reduce bounce rates and increase conversions. (Source: Headless CMS Checklist)

Getting Started & Support

How easy is it to get started with Hygraph?

Hygraph is designed for ease of use, with an intuitive interface that allows even non-technical users to get started quickly. You can sign up for a free-forever account and access comprehensive documentation, video tutorials, and onboarding guides. (Source: Hygraph Documentation)

What support options are available for Hygraph users?

Hygraph offers 24/7 support via chat, email, and phone. Enterprise customers receive dedicated onboarding and expert guidance. All users have access to detailed documentation, video tutorials, and a community Slack channel for additional help. (Source: Hygraph Contact Page)

Pricing & Plans

What is Hygraph's pricing model?

Hygraph offers a free forever Hobby plan, a Growth plan starting at $199/month, and custom Enterprise plans. For more details, visit the Hygraph Pricing Page.

Use Cases, Benefits & Customer Success

Who can benefit from using Hygraph?

Hygraph is ideal for developers, IT decision-makers, content creators, project/program managers, agencies, solution partners, and technology partners. It is especially beneficial for modern software companies, enterprises looking to modernize their tech stack, and brands aiming to scale across geographies or improve development velocity. (Source: ICPVersion2_Hailey.pdf)

What business impact can customers expect from using Hygraph?

Customers can expect significant business impacts, including time savings through streamlined workflows, faster speed-to-market, improved customer experience, and enhanced scalability. For example, Komax achieved a 3X faster time to market, and Autoweb saw a 20% increase in website monetization. (Source: Hygraph Product Page)

What industries are represented in Hygraph's customer case studies?

Hygraph's case studies span industries such as food and beverage (Dr. Oetker), consumer electronics (Samsung), automotive (AutoWeb), healthcare (Vision Healthcare), travel and hospitality (HolidayCheck), media and publishing, eCommerce, SaaS (Bellhop), marketplace, education technology, and wellness and fitness. (Source: Hygraph Case Studies)

Can you share some customer success stories with Hygraph?

Yes. Komax achieved a 3X faster time to market, Autoweb saw a 20% increase in website monetization, Samsung improved customer engagement with a scalable platform, and Dr. Oetker enhanced their digital experience using MACH architecture. More stories are available on the Hygraph Product Page.

Technical Documentation & Learning Resources

Where can I find technical documentation for Hygraph?

Comprehensive technical documentation for Hygraph is available at Hygraph Documentation. This includes guides on building and deploying projects, API references, and integration tutorials.

What learning resources are available for GraphQL and Hygraph?

Hygraph provides a range of learning resources, including the GraphQL Academy, blog tutorials, case studies, and a GraphQL Playground for hands-on experimentation. These resources help users understand GraphQL concepts, best practices, and how to implement real-time features like subscriptions. (Source: Hygraph GraphQL Subscriptions Guide)

Webinar Event: How to Avoid Personalization Tech Traps

GraphQL

Subscriptions

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.

Building A GraphQL Server

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

import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone'
import { gql } from 'graphql-tag';
const products = [
{
id: '1',
name: 'Daikin 1.5T',
category: 'Air Conditioners',
},
{
id: '2',
name: 'God Of War',
category: 'Gaming',
}
];

Schema

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.

const resolvers = {
Query: {
getAllProducts: () => products,
getProductById: (parent, args, contextValue, info) => products.find((product) => args.id === product.id)
},
};

Create an Apollo Server Instance and start the server

const server = new ApolloServer({
typeDefs: schema,
resolvers,
});
startStandaloneServer(server, { listen: { port: 4000 } }).then(({ url }) => {
console.log(`🚀 Apollo Server listening at: ${url}`);
});

Here is the complete file:

import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone'
import { gql } from 'graphql-tag';
const products = [
{
id: '1',
name: 'Daikin 1.5T',
category: 'Air Conditioners',
},
{
id: '2',
name: 'God Of War',
category: 'Gaming',
}
];
const typeDefs = gql`
type Product {
id: ID!
name: String
category: String
}
type Query {
getProductById(id: ID!): Product
getAllProducts: [Product]
}
`;
const resolvers = {
Query: {
getAllProducts: () => products,
getProductById: (parent, args, contextValue, info) => products.find((product) => args.id === product.id)
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
});
startStandaloneServer(server, { listen: { port: 4000 } }).then(({ url }) => {
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.

getAllProducts

getProductById.png

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-subscriptions graphql-ws ws @graphql-tools/schema apollo-server-express express body-parser cors

Let us create a new file named wsIndex.js and add our imports.

import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import { createServer } from 'http';
import { makeExecutableSchema } from '@graphql-tools/schema';
import { WebSocketServer } from 'ws';
import { useServer } from 'graphql-ws/lib/use/ws';
import { PubSub } from 'graphql-subscriptions';
import { gql } from 'graphql-tag';
import express from 'express';
import bodyParser from 'body-parser';
import cors from 'cors';
async function startServer() {
// main implementation goes here
}
startServer()

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.

const pubsub = new PubSub();
const resolvers = {
Query: {
userStatus() {
return userStatus;
},
},
Subscription: {
userStatusUpdated: {
subscribe: () => pubsub.asyncIterator(['USER_STATUS_UPDATED']),
},
},
};

Create the GraphQL schema from TypeDefs and Resolvers:

const schema = makeExecutableSchema({ typeDefs, resolvers });

Create an express app and an HTTP Server for our HTTP requests:

const app = express();
const httpServer = createServer(app);

Create a Websocket Server and its cleanup to support our Websocket operations:

const wsServer = new WebSocketServer({
server: httpServer,
path: '/',
});
const serverCleanup = useServer({ schema }, wsServer);

Create an ApolloServer instance, and add plugins for the proper shutdown of HTTP and WebSocket instances respectively.

const server = new ApolloServer({
schema,
plugins: [
ApolloServerPluginDrainHttpServer({ httpServer }),
{
async serverWillStart() {
return {
async drainServer() {
await serverCleanup.dispose();
},
};
},
},
],
});
await server.start();
app.use('/', cors(), bodyParser.json(), expressMiddleware(server));

Start listening with the help of our HTTP server:

const PORT = 4000;
httpServer.listen(PORT, () => {
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.

let userStatus = {
userId: "ceqak08y3sjkbasdfausjg",
isOnline: true
};
function toggleUserStatus() {
userStatus.isOnline = !userStatus.isOnline;
pubsub.publish('USER_STATUS_UPDATED', { userStatusUpdated: userStatus });
setTimeout(toggleUserStatus, 5000);
}
toggleUserStatus()

That’s it. Here’s the complete file wsIndex.js.

import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import { createServer } from 'http';
import { makeExecutableSchema } from '@graphql-tools/schema';
import { WebSocketServer } from 'ws';
import { useServer } from 'graphql-ws/lib/use/ws';
import { PubSub } from 'graphql-subscriptions';
import { gql } from 'graphql-tag';
import express from 'express';
import bodyParser from 'body-parser';
import cors from 'cors';
async function startServer() {
const typeDefs = gql`
type UserStatus {
userId: String!
isOnline: Boolean!
}
type Query {
userStatus: UserStatus!
}
type Subscription {
userStatusUpdated: UserStatus!
}
`;
const pubsub = new PubSub();
const resolvers = {
Query: {
userStatus() {
return userStatus;
},
},
Subscription: {
userStatusUpdated: {
subscribe: () => pubsub.asyncIterator(['USER_STATUS_UPDATED']),
},
},
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
const app = express();
const httpServer = createServer(app);
const wsServer = new WebSocketServer({
server: httpServer,
path: '/',
});
const serverCleanup = useServer({ schema }, wsServer);
const server = new ApolloServer({
schema,
plugins: [
ApolloServerPluginDrainHttpServer({ httpServer }),
{
async serverWillStart() {
return {
async drainServer() {
await serverCleanup.dispose();
},
};
},
},
],
});
await server.start();
app.use('/', cors(), bodyParser.json(), expressMiddleware(server));
const PORT = 4000;
httpServer.listen(PORT, () => {
console.log(`🚀 GraphQL Server ready at http://localhost:${PORT}/`);
console.log(`🚀 GraphQL WS ready at ws://localhost:${PORT}/`);
});
let userStatus = {
userId: "ceqak08y3sjkbasdfausjg",
isOnline: true
};
function toggleUserStatus() {
userStatus.isOnline = !userStatus.isOnline;
pubsub.publish('USER_STATUS_UPDATED', { userStatusUpdated: userStatus });
setTimeout(toggleUserStatus, 5000);
}
toggleUserStatus()
}
startServer()

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.