class GraphQL::Schema::Subscription

Also, ‘#unsubscribe` terminates the subscription.
- `#update`: called for subsequent update
- `#subscribe`: called for the initial subscription
- `#authorized?`: called before initial subscription and subsequent updates
It provides hooks for the different parts of the subscription lifecycle:
This class can be extended to create fields on your subscription root.

def self.subscription_scope(new_scope = NOT_CONFIGURED, optional: false)

Returns:
  • (Symbol) -

Parameters:
  • optional (Boolean) -- If true, then don't require `scope:` to be provided to updates to this subscription.
  • new_scope (Symbol) --
def self.subscription_scope(new_scope = NOT_CONFIGURED, optional: false)
  if new_scope != NOT_CONFIGURED
    @subscription_scope = new_scope
    @subscription_scope_optional = optional
  elsif defined?(@subscription_scope)
    @subscription_scope
  else
    find_inherited_value(:subscription_scope)
  end
end

def self.subscription_scope_optional?

def self.subscription_scope_optional?
  if defined?(@subscription_scope_optional)
    @subscription_scope_optional
  else
    find_inherited_value(:subscription_scope_optional, false)
  end
end

def self.topic_for(arguments:, field:, scope:)

Returns:
  • (String) - An identifier corresponding to a stream of updates

Parameters:
  • scope (Object, nil) -- A value corresponding to `.trigger(... scope:)` (for updates) or the `subscription_scope` found in `context` (for initial subscriptions).
  • field (GraphQL::Schema::Field) --
  • arguments (Hash Object>) -- The arguments for this topic, in GraphQL-style (camelized strings)

Other tags:
    See: {#update} - for how to skip updates when an event comes with a matching topic.
def self.topic_for(arguments:, field:, scope:)
  Subscriptions::Serialize.dump_recursive([scope, field.graphql_name, arguments])
end

def event

Returns:
  • (Subscriptions::Event) - This object is used as a representation of this subscription for the backend
def event
  @event ||= Subscriptions::Event.new(
    name: field.name,
    arguments: @original_arguments,
    context: context,
    field: field,
  )
end

def initialize(object:, context:, field:)

Other tags:
    Api: - private
def initialize(object:, context:, field:)
  super
  # Figure out whether this is an update or an initial subscription
  @mode = context.query.subscription_update? ? :update : :subscribe
  @subscription_written = false
  @original_arguments = nil
  if (subs_ns = context.namespace(:subscriptions)) &&
    (sub_insts = subs_ns[:subscriptions])
    sub_insts[context.current_path] = self
  end
end

def load_application_object_failed(err)

or that it became inaccessible).
remove this subscription (assuming that the object was deleted in the meantime,
If an argument is flagged with `loads:` and no object is found for it,
def load_application_object_failed(err)
  if @mode == :update
    unsubscribe
  end
  super
end

def resolve(**args)

and for later updates. Or, implement {#subscribe} and {#update}
You can implement this if you want code to run for _both_ the initial subscription
Implement the {Resolve} API.
def resolve(**args)
  # Dispatch based on `@mode`, which will raise a `NoMethodError` if we ever
  # have an unexpected `@mode`
  public_send("resolve_#{@mode}", **args)
end

def resolve_subscribe(**args)

Other tags:
    Api: - private
def resolve_subscribe(**args)
  ret_val = !args.empty? ? subscribe(**args) : subscribe
  if ret_val == :no_response
    context.skip
  else
    ret_val
  end
end

def resolve_update(**args)

Other tags:
    Api: - private
def resolve_update(**args)
  ret_val = !args.empty? ? update(**args) : update
  if ret_val == NO_UPDATE
    context.namespace(:subscriptions)[:no_update] = true
    context.skip
  else
    ret_val
  end
end

def resolve_with_support(**args)

Other tags:
    Api: - private
def resolve_with_support(**args)
  @original_arguments = args # before `loads:` have been run
  result = nil
  unsubscribed = true
  unsubscribed_result = catch :graphql_subscription_unsubscribed do
    result = super
    unsubscribed = false
  end
  if unsubscribed
    if unsubscribed_result
      context.namespace(:subscriptions)[:final_update] = true
      unsubscribed_result
    else
      context.skip
    end
  else
    result
  end
end

def subscribe(args = {})

`:no_response` to (explicitly) return nothing.
Override it to return an object or
The default implementation returns nothing on subscribe.
def subscribe(args = {})
  :no_response
end

def subscription_written?

Returns:
  • (Boolean) - `true` if {#write_subscription} was called already
def subscription_written?
  @subscription_written
end

def unsubscribe(update_value = nil)

Returns:
  • (void) -

Parameters:
  • update_value (Object) -- if present, deliver this update before unsubscribing
def unsubscribe(update_value = nil)
  context.namespace(:subscriptions)[:unsubscribed] = true
  throw :graphql_subscription_unsubscribed, update_value
end

def update(args = {})

skip updates sometimes. Or override it to return a different object.
Override it to return {NO_UPDATE} if you want to
The default implementation returns the root object.
def update(args = {})
  object
end

def write_subscription

Returns:
  • (void) -
def write_subscription
  if subscription_written?
    raise GraphQL::Error, "`write_subscription` was called but `#{self.class}#subscription_written?` is already true. Remove a call to `write subscription`."
  else
    @subscription_written = true
    context.schema.subscriptions.write_subscription(context.query, [event])
  end
  nil
end