Class: GraphQL::Subscriptions

Inherits:
Object
  • Object
show all
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

ActionCableSubscriptions

Defined Under Namespace

Modules: Serialize Classes: ActionCableSubscriptions, Event, Instrumentation

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(schema:, **rest) ⇒ Subscriptions


22
23
24
# File 'lib/graphql/subscriptions.rb', line 22

def initialize(kwargs)
  @schema = kwargs[:schema]
end

Class Method Details

.use(defn, options = {}) ⇒ Object


12
13
14
15
16
17
18
19
20
# File 'lib/graphql/subscriptions.rb', line 12

def self.use(defn, options = {})
  schema = defn.target
  options[:schema] = schema
  schema.subscriptions = self.new(options)
  instrumentation = Subscriptions::Instrumentation.new(schema: schema)
  defn.instrument(:field, instrumentation)
  defn.instrument(:query, instrumentation)
  nil
end

Instance Method Details

#build_idString


139
140
141
# File 'lib/graphql/subscriptions.rb', line 139

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`.

Raises:

  • (NotImplementedError)

125
126
127
# File 'lib/graphql/subscriptions.rb', line 125

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

Yield Parameters:

  • subscription_id (String)

Raises:

  • (NotImplementedError)

107
108
109
# File 'lib/graphql/subscriptions.rb', line 107

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.


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/graphql/subscriptions.rb', line 70

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.


97
98
99
100
101
# File 'lib/graphql/subscriptions.rb', line 97

def execute_all(event, object)
  each_subscription_id(event) do |subscription_id|
    execute(subscription_id, event, object)
  end
end

#read_subscription(subscription_id) ⇒ Hash

The system wants to send an update to this subscription. Read its data and return it.

Raises:

  • (NotImplementedError)

115
116
117
# File 'lib/graphql/subscriptions.rb', line 115

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.


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/graphql/subscriptions.rb', line 33

def trigger(event_name, args, object, scope: nil)
  field = @schema.get_field("Subscription", event_name)
  if !field
    raise "No subscription matching trigger: #{event_name}"
  end

  # Normalize symbol-keyed args to strings
  if args.any?
    stringified_args = {}
    args.each { |k, v| stringified_args[k.to_s] = v }
    args = stringified_args
  end

  event = Subscriptions::Event.new(
    name: event_name,
    arguments: 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.

Raises:

  • (NotImplementedError)

134
135
136
# File 'lib/graphql/subscriptions.rb', line 134

def write_subscription(query, events)
  raise NotImplementedError
end