Class: GraphQL::Subscriptions
- Inherits:
-
Object
- Object
- GraphQL::Subscriptions
- Defined in:
- lib/graphql/subscriptions.rb,
lib/graphql/subscriptions/event.rb,
lib/graphql/subscriptions/serialize.rb,
lib/graphql/subscriptions/instrumentation.rb,
lib/graphql/subscriptions/action_cable_subscriptions.rb
Direct Known Subclasses
Defined Under Namespace
Modules: Serialize Classes: ActionCableSubscriptions, Event, Instrumentation, InvalidTriggerError
Class Method Summary collapse
Instance Method Summary collapse
-
#build_id ⇒ String
A new unique identifier for a subscription.
-
#deliver(subscription_id, result, context) ⇒ void
A subscription query was re-evaluated, returning
result. -
#each_subscription_id(event) {|subscription_id| ... } ⇒ void
Get each
subscription_idsubscribed toevent.topicand yield them. -
#execute(subscription_id, event, object) ⇒ void
eventwas triggered onobject, andsubscription_idwas subscribed, so it should be updated. -
#execute_all(event, object) ⇒ void
Event
eventoccurred onobject, Update all subscribers. -
#initialize(schema:, **rest) ⇒ Subscriptions
constructor
A new instance of Subscriptions.
-
#normalize_name(event_or_arg_name) ⇒ String
Convert a user-provided event name or argument to the equivalent in GraphQL.
-
#read_subscription(subscription_id) ⇒ Hash
The system wants to send an update to this subscription.
-
#trigger(event_name, args, object, scope: nil) ⇒ void
Fetch subscriptions matching this field + arguments pair And pass them off to the queue.
-
#write_subscription(query, events) ⇒ void
querywas executed and found subscriptions toevents.
Constructor Details
#initialize(schema:, **rest) ⇒ Subscriptions
Returns a new instance of Subscriptions
30 31 32 |
# File 'lib/graphql/subscriptions.rb', line 30 def initialize(schema:, **rest) @schema = schema end |
Class Method Details
.use(defn, options = {}) ⇒ Object
19 20 21 22 23 24 25 26 27 |
# File 'lib/graphql/subscriptions.rb', line 19 def self.use(defn, = {}) schema = defn.target [:schema] = schema schema.subscriptions = self.new() instrumentation = Subscriptions::Instrumentation.new(schema: schema) defn.instrument(:field, instrumentation) defn.instrument(:query, instrumentation) nil end |
Instance Method Details
#build_id ⇒ String
Returns A new unique identifier for a subscription
151 152 153 |
# File 'lib/graphql/subscriptions.rb', line 151 def build_id SecureRandom.uuid end |
#deliver(subscription_id, result, context) ⇒ void
This method returns an undefined value.
A subscription query was re-evaluated, returning result.
The result should be send to subscription_id.
137 138 139 |
# File 'lib/graphql/subscriptions.rb', line 137 def deliver(subscription_id, result, context) raise NotImplementedError end |
#each_subscription_id(event) {|subscription_id| ... } ⇒ void
This method returns an undefined value.
Get each subscription_id subscribed to event.topic and yield them
119 120 121 |
# File 'lib/graphql/subscriptions.rb', line 119 def each_subscription_id(event) raise NotImplementedError end |
#execute(subscription_id, event, object) ⇒ void
This method returns an undefined value.
event was triggered on object, and subscription_id was subscribed,
so it should be updated.
Load subscription_id’s GraphQL data, re-evaluate the query, and deliver the result.
This is where a queue may be inserted to push updates in the background.
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/graphql/subscriptions.rb', line 82 def execute(subscription_id, event, object) # Lookup the saved data for this subscription query_data = read_subscription(subscription_id) # Fetch the required keys from the saved data query_string = query_data.fetch(:query_string) variables = query_data.fetch(:variables) context = query_data.fetch(:context) operation_name = query_data.fetch(:operation_name) # Re-evaluate the saved query result = @schema.execute( { query: query_string, context: context, subscription_topic: event.topic, operation_name: operation_name, variables: variables, root_value: object, } ) deliver(subscription_id, result) end |
#execute_all(event, object) ⇒ void
This method returns an undefined value.
Event event occurred on object,
Update all subscribers.
109 110 111 112 113 |
# File 'lib/graphql/subscriptions.rb', line 109 def execute_all(event, object) each_subscription_id(event) do |subscription_id| execute(subscription_id, event, object) end end |
#normalize_name(event_or_arg_name) ⇒ String
Convert a user-provided event name or argument to the equivalent in GraphQL.
By default, it converts the identifier to camelcase. Override this in a subclass to change the transformation.
163 164 165 |
# File 'lib/graphql/subscriptions.rb', line 163 def normalize_name(event_or_arg_name) Schema::Member::BuildType.camelize(event_or_arg_name.to_s) end |
#read_subscription(subscription_id) ⇒ Hash
The system wants to send an update to this subscription. Read its data and return it.
127 128 129 |
# File 'lib/graphql/subscriptions.rb', line 127 def read_subscription(subscription_id) raise NotImplementedError end |
#trigger(event_name, args, object, scope: nil) ⇒ void
This method returns an undefined value.
Fetch subscriptions matching this field + arguments pair And pass them off to the queue.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/graphql/subscriptions.rb', line 41 def trigger(event_name, args, object, scope: nil) event_name = event_name.to_s # Try with the verbatim input first: field = @schema.get_field("Subscription", event_name) if field.nil? # And if it wasn't found, normalize it: normalized_event_name = normalize_name(event_name) field = @schema.get_field("Subscription", normalized_event_name) if field.nil? raise InvalidTriggerError, "No subscription matching trigger: #{event_name} (looked for #{@schema.subscription.graphql_name}.#{normalized_event_name})" end else # Since we found a field, the original input was already normalized normalized_event_name = event_name end # Normalize symbol-keyed args to strings, try camelizing them normalized_args = normalize_arguments(normalized_event_name, field, args) event = Subscriptions::Event.new( name: normalized_event_name, arguments: normalized_args, field: field, scope: scope, ) execute_all(event, object) end |
#write_subscription(query, events) ⇒ void
This method returns an undefined value.
query was executed and found subscriptions to events.
Update the database to reflect this new state.
146 147 148 |
# File 'lib/graphql/subscriptions.rb', line 146 def write_subscription(query, events) raise NotImplementedError end |