Broadcasts

GraphQL-Ruby 1.11+ introduced a new algorithm for tracking subscriptions and delivering updates, broadcasts.

A broadcast is a subscription update which is executed once, then delivered to any number of subscribers. This reduces the time your server spends running GraphQL queries, since it doesn’t have to re-run the query for every subscriber.

But, take care: this approach risks leaking information to subscribers who shouldn’t receive it.

Setup

To enable broadcasts, add broadcast: true to your subscription setup:

class MyAppSchema < GraphQL::Schema
  # ...
  use GraphQL::Execution::Interpreter
  use GraphQL::Analysis::AST
  use SomeSubscriptionImplementation,
    broadcast: true # <----
end

Then, any broadcastable field can be configured with broadcastable: true:

field :name, String, null: false,
  broadcastable: true

When a subscription comes in where all of its fields are broadcastable: true, then it will be handled as a broadcast.

Additionally, you can set default_broadcastable: true:

class MyAppSchema < GraphQL::Schema
  # ...
  use GraphQL::Execution::Interpreter
  use GraphQL::Analysis::AST
  use SomeSubscriptionImplementation,
    broadcast: true,
    default_broadcastable: true # <----
end

With this setting, fields are broadcastable by default. Only a field with broadcastable: false in its configuration will cause a subscription to be handled on a subscriber-by-subscriber basis.

What fields are broadcastable?

GraphQL-Ruby can’t infer whether a field is broadcastable or not. You must configure it explicitly with broadcastable: true or broadcastable: false. (The subscription plugin also accepts default_broadcastable: true|false.)

A field is broadcastable if all clients who request the field will see the same value. For example:

For fields like this, you can add broadcastable: true.

A field is not broadcastable if its value is different for different clients. For example:

These fields can be tagged with broadcastable: false so that GraphQL-Ruby will handle them on a subscriber-by-subscriber basis.

If you want to use subscriptions but have a lot of non-broadcastable fields in your schema, consider building a new set of subscription fields with limited access to other schema objects. Instead, optimize those subscriptions for broacastability.

Under the Hood

GraphQL-Ruby determines which subscribers can receive a broadcast by inspecting:

So, take care to set subscription_scope whenever a subscription should be implicitly scoped!

(See GraphQL::Subscriptions::Event#fingerprint for the implementation of broadcast fingerprints.)