-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
batch_loading.rb
138 lines (112 loc) · 3.28 KB
/
batch_loading.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# frozen_string_literal: true
module BatchLoading
class GraphQLBatchSchema < GraphQL::Schema
DATA = [
{ id: "1", name: "Bulls", player_ids: ["2", "3"] },
{ id: "2", name: "Michael Jordan", team_id: "1" },
{ id: "3", name: "Scottie Pippin", team_id: "1" },
{ id: "4", name: "Braves", player_ids: ["5", "6"] },
{ id: "5", name: "Chipper Jones", team_id: "4" },
{ id: "6", name: "Tom Glavine", team_id: "4" },
]
class DataLoader < GraphQL::Batch::Loader
def initialize(column: :id)
@column = column
end
def perform(keys)
keys.each do |key|
record = DATA.find { |d| d[@column] == key }
fulfill(key, record)
end
end
end
class Team < GraphQL::Schema::Object
field :name, String, null: false
field :players, "[BatchLoading::GraphQLBatchSchema::Player]", null: false
def players
DataLoader.load_many(object[:player_ids])
end
end
class Player < GraphQL::Schema::Object
field :name, String, null: false
field :team, Team, null: false
def team
DataLoader.load(object[:team_id])
end
end
class Query < GraphQL::Schema::Object
field :team, Team do
argument :name, String
end
def team(name:)
DataLoader.for(column: :name).load(name)
end
end
query(Query)
use GraphQL::Batch
end
class GraphQLDataloaderSchema < GraphQL::Schema
class DataSource < GraphQL::Dataloader::Source
def initialize(options = {column: :id})
@column = options[:column]
end
def fetch(keys)
keys.map { |key|
d = GraphQLBatchSchema::DATA.find { |d| d[@column] == key }
# p [key, @column, d]
d
}
end
end
class Team < GraphQL::Schema::Object
field :name, String, null: false
field :players, "[BatchLoading::GraphQLDataloaderSchema::Player]", null: false
def players
dataloader.with(DataSource).load_all(object[:player_ids])
end
end
class Player < GraphQL::Schema::Object
field :name, String, null: false
field :team, Team, null: false
def team
dataloader.with(DataSource).load(object[:team_id])
end
end
class Query < GraphQL::Schema::Object
field :team, Team do
argument :name, String
end
def team(name:)
dataloader.with(DataSource, column: :name).load(name)
end
end
query(Query)
use GraphQL::Dataloader
end
class GraphQLNoBatchingSchema < GraphQL::Schema
DATA = GraphQLBatchSchema::DATA
class Team < GraphQL::Schema::Object
field :name, String, null: false
field :players, "[BatchLoading::GraphQLNoBatchingSchema::Player]", null: false
def players
object[:player_ids].map { |id| DATA.find { |d| d[:id] == id } }
end
end
class Player < GraphQL::Schema::Object
field :name, String, null: false
field :team, Team, null: false
def team
DATA.find { |d| d[:id] == object[:team_id] }
end
end
class Query < GraphQL::Schema::Object
field :team, Team do
argument :name, String
end
def team(name:)
DATA.find { |d| d[:name] == name }
end
end
query(Query)
end
end