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