Reduce real-time cloud spend with Federated Subscriptions support for HTTP Callbacks
Andrew I. Carlson
Modern apps must support real-time use cases like flight changes, team collaboration, or live score updates for the big game. GraphQL subscriptions push events in a more efficient and performant way compared to traditional client-side polling of RESTful services that try to pull new events every few seconds. Instead of polling, clients can subscribe to the specific data they require, and the graph immediately delivers those events as they occur, reducing backend load and providing faster real-time updates.
Traditionally, GraphQL subscriptions have been implemented with WebSockets, an approach with many issues, including compression, debugging, scalability, and compatibility with firewalls, load-balancers, and other networking infrastructure.
We addressed the frontend portion of the WebSocket problem in June 2023, when we announced Federated subscriptions in GraphOS with support for a new HTTP multipart protocol based on the underlying protocol for GraphQL @defer support in Apollo Router. This makes hosting a real-time API in any cloud environment easier, with all the benefits of a standard HTTP connection.
However, on the backend, Apollo Router supports legacy WebSocket protocols for compatibility with existing subgraph APIs, which is inefficient at scale. For example, if a subscription can’t be deduplicated, 1 million client subscriptions would require 1 million backend WebSockets connections.
Today, we are excited to announce the GA release of Apollo Router 1.37 with HTTP callback support, designed in partnership with the GraphQL community. HTTP callback support solves the backend WebSocket problem and dramatically reduces the number of open subgraph connections. This results in the same great performance but with more efficiency at scale and reduces real-time cloud spend for router and subgraph deployments.
Subscription callbacks offer new levels of flexibility and interoperability between the router and underlying services. By default, federated subscriptions use WebSockets, which requires two long-lived connections for every client: one between the client and the router and one between the router and the subgraph. Additionally, these long-lived connections aren’t well suited for serverless infrastructures.
With HTTP callbacks, on the other hand, the router no longer manages a WebSocket connection with subgraphs, and it’s flexible enough to be used with other Pub/Sub architectures that can support HTTP requests.
HTTP Callbacks for Federated Subscriptions
Here’s what you’ll need to use federated subscriptions with self-hosted instances of Apollo Router:
- An active Apollo GraphOS Enterprise plan
- A federated GraphQL API with
- The latest version of Apollo Client (Web, iOS, or Kotlin) with HTTP-based subscriptions support.
If you don’t have a GraphOS Enterprise plan and you need to self-host the Apollo Router for an enterprise-scale deployment, try out GraphOS Enterprise for free for 28 days.
Migrating from the preview to GA
If your application already uses the preview of subscription callbacks, there are a few things to change in your Router configuration to migrate to the GA:
- Change the name of the option from
subscription.mode.callback. Failure to use the updated option name when running the router will result in an error, and the router won’t start.
- Update the
public_urlfield to include the full URL of your callback endpoint. Previously, in the preview, the public URL used by the router was the automatic concatenation of the
pathfields. In GA, the behavior has changed, and the router uses the value set in
public_url. This enables you to configure your public URL, for example, if you have a proxy in front of the router and want to configure redirection with the public URL.
- Configure the new
heartbeat_intervalfield to set the period that a heartbeat must be sent to the callback endpoint for the subscription operation. The default heartbeat interval is 5 seconds. You can turn off heartbeats, for example, if you’re operating in a serverless architecture without long-lived processes, by setting