Class: GraphQL::Schema::Subscription
- Extended by:
- Member::HasFields, Resolver::HasPayloadType
- Defined in:
- lib/graphql/schema/subscription.rb
Overview
This class can be extended to create fields on your subscription root.
It provides hooks for the different parts of the subscription lifecycle:
#authorized?
: called before initial subscription and subsequent updates#subscribe
: called for the initial subscription#update
: called for subsequent update
Also, #unsubscribe
terminates the subscription.
Constant Summary collapse
- NO_UPDATE =
:no_update
- READING_SCOPE =
::Object.new
Constants included from Resolver::HasPayloadType
Resolver::HasPayloadType::NO_INTERFACES
Constants included from Member::HasFields
Member::HasFields::CONFLICT_FIELD_NAMES, Member::HasFields::GRAPHQL_RUBY_KEYWORDS, Member::HasFields::RUBY_KEYWORDS
Constants included from Member::HasArguments
Member::HasArguments::NO_ARGUMENTS
Constants included from FindInheritedValue::EmptyObjects
FindInheritedValue::EmptyObjects::EMPTY_ARRAY, FindInheritedValue::EmptyObjects::EMPTY_HASH
Constants included from Member::GraphQLTypeNames
Member::GraphQLTypeNames::Boolean, Member::GraphQLTypeNames::ID, Member::GraphQLTypeNames::Int
Instance Attribute Summary
Attributes inherited from Resolver
Class Method Summary collapse
-
.field_options ⇒ Object
Overriding Resolver#field_options to include subscription_scope.
-
.subscription_scope(new_scope = READING_SCOPE, optional: false) ⇒ Symbol
Call this method to provide a new subscription_scope; OR call it without an argument to get the subscription_scope.
-
.subscription_scope_optional? ⇒ Boolean
-
.topic_for(arguments:, field:, scope:) ⇒ String
This is called during initial subscription to get a “name” for this subscription.
Instance Method Summary collapse
-
#initialize(object:, context:, field:) ⇒ Subscription
constructor
A new instance of Subscription.
-
#load_application_object_failed(err) ⇒ Object
If an argument is flagged with
loads:
and no object is found for it, remove this subscription (assuming that the object was deleted in the meantime, or that it became inaccessible). -
#resolve(**args) ⇒ Object
Implement the Resolve API.
-
#resolve_subscribe(**args) ⇒ Object
Wrap the user-defined
#subscribe
hook. -
#resolve_update(**args) ⇒ Object
Wrap the user-provided
#update
hook. -
#resolve_with_support(**args) ⇒ Object
-
#subscribe(args = {}) ⇒ Object
The default implementation returns nothing on subscribe.
-
#unsubscribe ⇒ Object
Call this to halt execution and remove this subscription from the system.
-
#update(args = {}) ⇒ Object
The default implementation returns the root object.
Methods included from Resolver::HasPayloadType
field, field_class, object_class, payload_type
Methods included from Member::HasFields
add_field, all_field_definitions, field, field_class, fields, get_field, global_id_field, own_fields
Methods inherited from Resolver
argument, #arguments, #authorized?, broadcastable, broadcastable?, complexity, #dataloader, extension, extensions, extras, has_max_page_size?, max_page_size, null, #ready?, resolve_method, type, type_expr, #unauthorized_object
Methods included from Member::BaseDSLMethods
#accessible?, #authorized?, #default_graphql_name, #description, #graphql_name, #introspection, #introspection?, #mutation, #name, #overridden_graphql_name, #visible?
Methods included from Member::HasArguments
#add_argument, #all_argument_definitions, #argument, #argument_class, #arguments, #arguments_statically_coercible?, #coerce_arguments, #get_argument, #own_arguments, #validate_directive_argument
Methods included from Member::HasValidators
Methods included from Member::HasPath
Constructor Details
#initialize(object:, context:, field:) ⇒ Subscription
Returns a new instance of Subscription.
22 23 24 25 26 |
# File 'lib/graphql/schema/subscription.rb', line 22 def initialize(object:, context:, field:) super # Figure out whether this is an update or an initial subscription @mode = context.query.subscription_update? ? :update : :subscribe end |
Class Method Details
.field_options ⇒ Object
Overriding Resolver#field_options to include subscription_scope
148 149 150 151 152 |
# File 'lib/graphql/schema/subscription.rb', line 148 def self. super.merge( subscription_scope: subscription_scope ) end |
.subscription_scope(new_scope = READING_SCOPE, optional: false) ⇒ Symbol
Call this method to provide a new subscription_scope; OR call it without an argument to get the subscription_scope
108 109 110 111 112 113 114 115 116 117 |
# File 'lib/graphql/schema/subscription.rb', line 108 def self.subscription_scope(new_scope = READING_SCOPE, optional: false) if new_scope != READING_SCOPE @subscription_scope = new_scope @subscription_scope_optional = optional elsif defined?(@subscription_scope) @subscription_scope else find_inherited_value(:subscription_scope) end end |
.subscription_scope_optional? ⇒ Boolean
119 120 121 122 123 124 125 |
# File 'lib/graphql/schema/subscription.rb', line 119 def self.subscription_scope_optional? if defined?(@subscription_scope_optional) @subscription_scope_optional else find_inherited_value(:subscription_scope_optional, false) end end |
.topic_for(arguments:, field:, scope:) ⇒ String
This is called during initial subscription to get a “name” for this subscription.
Later, when .trigger
is called, this will be called again to build another “name”.
Any subscribers with matching topic will begin the update flow.
The default implementation creates a string using the field name, subscription scope, and argument keys and values.
In that implementation, only .trigger
calls with exact matches result in updates to subscribers.
To implement a filtered stream-type subscription flow, override this method to return a string with field name and subscription scope.
Then, implement #update to compare its arguments to the current object
and return NO_UPDATE when an
update should be filtered out.
143 144 145 |
# File 'lib/graphql/schema/subscription.rb', line 143 def self.topic_for(arguments:, field:, scope:) Subscriptions::Serialize.dump_recursive([scope, field.graphql_name, arguments]) end |
Instance Method Details
#load_application_object_failed(err) ⇒ Object
If an argument is flagged with loads:
and no object is found for it,
remove this subscription (assuming that the object was deleted in the meantime,
or that it became inaccessible).
89 90 91 92 93 94 |
# File 'lib/graphql/schema/subscription.rb', line 89 def load_application_object_failed(err) if @mode == :update unsubscribe end super end |
#resolve(**args) ⇒ Object
Implement the Resolve API
45 46 47 48 49 |
# File 'lib/graphql/schema/subscription.rb', line 45 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 |
#resolve_subscribe(**args) ⇒ Object
Wrap the user-defined #subscribe
hook
52 53 54 55 56 57 58 59 |
# File 'lib/graphql/schema/subscription.rb', line 52 def resolve_subscribe(**args) ret_val = args.any? ? subscribe(**args) : subscribe if ret_val == :no_response context.skip else ret_val end end |
#resolve_update(**args) ⇒ Object
Wrap the user-provided #update
hook
69 70 71 72 73 74 75 76 77 |
# File 'lib/graphql/schema/subscription.rb', line 69 def resolve_update(**args) ret_val = args.any? ? update(**args) : update if ret_val == NO_UPDATE context.namespace(:subscriptions)[:no_update] = true context.skip else ret_val end end |
#resolve_with_support(**args) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/graphql/schema/subscription.rb', line 28 def resolve_with_support(**args) result = nil unsubscribed = true catch :graphql_subscription_unsubscribed do result = super unsubscribed = false end if unsubscribed context.skip else result end end |
#subscribe(args = {}) ⇒ Object
The default implementation returns nothing on subscribe.
Override it to return an object or
:no_response
to (explicitly) return nothing.
64 65 66 |
# File 'lib/graphql/schema/subscription.rb', line 64 def subscribe(args = {}) :no_response end |
#unsubscribe ⇒ Object
Call this to halt execution and remove this subscription from the system
97 98 99 100 |
# File 'lib/graphql/schema/subscription.rb', line 97 def unsubscribe context.namespace(:subscriptions)[:unsubscribed] = true throw :graphql_subscription_unsubscribed end |