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 EmptyObjects
EmptyObjects::EMPTY_ARRAY, EmptyObjects::EMPTY_HASH
Constants included from Member::GraphQLTypeNames
Member::GraphQLTypeNames::Boolean, Member::GraphQLTypeNames::ID, Member::GraphQLTypeNames::Int
Instance Attribute Summary
Attributes inherited from Resolver
Attributes included from Member::BaseDSLMethods
#default_graphql_name, #graphql_name
Class Method Summary collapse
-
.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(update_value = nil) ⇒ void
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, type
Methods included from Member::HasFields
add_field, all_field_definitions, field, field_class, global_id_field, has_no_fields, has_no_fields?, own_fields
Methods inherited from Resolver
all_field_argument_definitions, any_field_arguments?, argument, #arguments, #authorized?, broadcastable, broadcastable?, #call_resolve, complexity, #dataloader, default_page_size, extension, extensions, extras, field_arguments, get_field_argument, has_default_page_size?, has_max_page_size?, max_page_size, null, #ready?, resolve_method, resolver_method, type, type_expr, #unauthorized_object
Methods included from Member::BaseDSLMethods
#authorized?, #comment, #default_relay, #description, #introspection, #introspection?, #mutation, #name, #visible?
Methods included from Member::HasArguments
#add_argument, #all_argument_definitions, #any_arguments?, #argument, #argument_class, #arguments, #arguments_statically_coercible?, #coerce_arguments, #get_argument, #own_arguments, #remove_argument, #validate_directive_argument
Methods included from Member::HasValidators
Methods included from Member::HasPath
Methods included from Member::HasDirectives
add_directive, #directive, #directives, get_directives, #inherited, #remove_directive, remove_directive
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
.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
115 116 117 118 119 120 121 122 123 124 |
# File 'lib/graphql/schema/subscription.rb', line 115 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
126 127 128 129 130 131 132 |
# File 'lib/graphql/schema/subscription.rb', line 126 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.
150 151 152 |
# File 'lib/graphql/schema/subscription.rb', line 150 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).
94 95 96 97 98 99 |
# File 'lib/graphql/schema/subscription.rb', line 94 def load_application_object_failed(err) if @mode == :update unsubscribe end super end |
#resolve(**args) ⇒ Object
Implement the Resolve API
50 51 52 53 54 |
# File 'lib/graphql/schema/subscription.rb', line 50 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
57 58 59 60 61 62 63 64 |
# File 'lib/graphql/schema/subscription.rb', line 57 def resolve_subscribe(**args) ret_val = !args.empty? ? 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
74 75 76 77 78 79 80 81 82 |
# File 'lib/graphql/schema/subscription.rb', line 74 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 |
#resolve_with_support(**args) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/graphql/schema/subscription.rb', line 28 def resolve_with_support(**args) 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 |
#subscribe(args = {}) ⇒ Object
The default implementation returns nothing on subscribe.
Override it to return an object or
:no_response
to (explicitly) return nothing.
69 70 71 |
# File 'lib/graphql/schema/subscription.rb', line 69 def subscribe(args = {}) :no_response end |
#unsubscribe(update_value = nil) ⇒ void
This method returns an undefined value.
Call this to halt execution and remove this subscription from the system
104 105 106 107 |
# File 'lib/graphql/schema/subscription.rb', line 104 def unsubscribe(update_value = nil) context.namespace(:subscriptions)[:unsubscribed] = true throw :graphql_subscription_unsubscribed, update_value end |