Skip to content

Subscriptions should default to allow null=true to improve performance #5488

@humphreyja

Description

@humphreyja

Is your feature request related to a problem? Please describe.

Initially discussed in #4345. Relay and Apollo expect the initial payload to match to the subscription event value. As a result, most subscriptions end up causing double work on your server. For example, if you are loading a table of 100 items and would like to receive subscription updates for when any one of those items change, you would create 100 subscriptions. This causes you to now load those 100 records AGAIN in the initial response to the subscription instead of only when an event happens. As a result you get a lot more traffic on your database.

Additionally, the default behavior of this Gem is to return an empty response for that initial subscription response which Relay and Apollo throw errors about because they expect at least the key for the subscription to be in the payload.

So the result is currently (which relay doesn't like since it doesn't match what you are asking):

result: {
  data: {}
}

when it should be:

result: {
  data: {
    mySubscription: null
  }
}

Describe the solution you'd like

You can get around this by doing the following:

class MySubscription < BaseSubscription
  type MyRecordType, null: true

  def subscribe(*)
    nil
  end
end

I think this is a chance to bring some unity to subscriptions and the rest of the gem by simplifying this to

class MySubscription < BaseSubscription
  type MyRecordType  # no need to specify null: true here because the default behavior everywhere is that null: true
end

Backwards Compatibility
I've found a few way to make this change backward compatible. The first is that people should start using the type declaration instead of payload_type. Seeing as subscriptions is the only documented thing to use the payload_type, having people use type instead brings subscriptions in alignment to mutations and resolvers.

Additionally, we should remove the need to specify null: true in subscriptions to also bring the behavior back in alignment to mutations and resolvers. As for backward support, devs can simply make the following change to their subscription base class to get the same behavior:

class BaseSubscription < GraphQL::Schema::Subscription
  null false
end

I'll have a PR in a minute that addresses these. Interested in what y'all think.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions