gqli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +31 -0
- data/.rubocop_todo.yml +44 -0
- data/.travis.yml +13 -0
- data/.yardopts +4 -0
- data/CHANGELOG.md +9 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +154 -0
- data/Guardfile +24 -0
- data/LICENSE.txt +21 -0
- data/README.md +284 -0
- data/Rakefile +33 -0
- data/coverage/.last_run.json +5 -0
- data/coverage/.resultset.json +512 -0
- data/coverage/.resultset.json.lock +0 -0
- data/coverage/assets/0.10.2/application.css +799 -0
- data/coverage/assets/0.10.2/application.js +1707 -0
- data/coverage/assets/0.10.2/colorbox/border.png +0 -0
- data/coverage/assets/0.10.2/colorbox/controls.png +0 -0
- data/coverage/assets/0.10.2/colorbox/loading.gif +0 -0
- data/coverage/assets/0.10.2/colorbox/loading_background.png +0 -0
- data/coverage/assets/0.10.2/favicon_green.png +0 -0
- data/coverage/assets/0.10.2/favicon_red.png +0 -0
- data/coverage/assets/0.10.2/favicon_yellow.png +0 -0
- data/coverage/assets/0.10.2/loading.gif +0 -0
- data/coverage/assets/0.10.2/magnify.png +0 -0
- data/coverage/assets/0.10.2/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/coverage/assets/0.10.2/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/coverage/assets/0.10.2/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/coverage/assets/0.10.2/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/coverage/assets/0.10.2/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/coverage/assets/0.10.2/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/coverage/assets/0.10.2/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/coverage/assets/0.10.2/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/coverage/index.html +3255 -0
- data/doc/GQLi/Base.html +628 -0
- data/doc/GQLi/Client.html +830 -0
- data/doc/GQLi/DSL.html +421 -0
- data/doc/GQLi/Fragment.html +405 -0
- data/doc/GQLi/Introspection.html +837 -0
- data/doc/GQLi/Node.html +413 -0
- data/doc/GQLi/Query.html +390 -0
- data/doc/GQLi/Response.html +370 -0
- data/doc/GQLi.html +157 -0
- data/doc/_index.html +236 -0
- data/doc/class_list.html +51 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +58 -0
- data/doc/css/style.css +496 -0
- data/doc/file.CHANGELOG.html +76 -0
- data/doc/file.LICENSE.html +70 -0
- data/doc/file.README.html +365 -0
- data/doc/file_list.html +66 -0
- data/doc/frames.html +17 -0
- data/doc/index.html +365 -0
- data/doc/js/app.js +292 -0
- data/doc/js/full_list.js +216 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +355 -0
- data/doc/top-level-namespace.html +110 -0
- data/gqli.gemspec +37 -0
- data/lib/gqli/base.rb +53 -0
- data/lib/gqli/client.rb +59 -0
- data/lib/gqli/dsl.rb +37 -0
- data/lib/gqli/fragment.rb +25 -0
- data/lib/gqli/introspection.rb +215 -0
- data/lib/gqli/node.rb +48 -0
- data/lib/gqli/query.rb +29 -0
- data/lib/gqli/response.rb +15 -0
- data/lib/gqli/version.rb +7 -0
- data/lib/gqli.rb +6 -0
- data/spec/fixtures/vcr_cassettes/catCollection.yml +63 -0
- data/spec/fixtures/vcr_cassettes/client.yml +171 -0
- data/spec/fixtures/vcr_cassettes/validation_error.yml +62 -0
- data/spec/lib/gqli/client_spec.rb +90 -0
- data/spec/lib/gqli/dsl_spec.rb +205 -0
- data/spec/lib/gqli/introspection_spec.rb +125 -0
- data/spec/spec_helper.rb +25 -0
- data/usage.rb +100 -0
- data/usage_introspection.rb +63 -0
- data/usage_with_inlined_dsl.rb +69 -0
- metadata +387 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe GQLi::Client do
|
|
4
|
+
let(:client) do
|
|
5
|
+
vcr('client') {
|
|
6
|
+
space_id = 'cfexampleapi'
|
|
7
|
+
token = 'b4c0n73n7fu1'
|
|
8
|
+
GQLi::Client.new(
|
|
9
|
+
"https://graphql.contentful.com/content/v1/spaces/#{space_id}",
|
|
10
|
+
headers: { "Authorization" => "Bearer #{token}" }
|
|
11
|
+
)
|
|
12
|
+
}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
let(:client_no_validations) do
|
|
16
|
+
vcr('client') {
|
|
17
|
+
space_id = 'cfexampleapi'
|
|
18
|
+
token = 'b4c0n73n7fu1'
|
|
19
|
+
GQLi::Client.new(
|
|
20
|
+
"https://graphql.contentful.com/content/v1/spaces/#{space_id}",
|
|
21
|
+
headers: { "Authorization" => "Bearer #{token}" },
|
|
22
|
+
validate_query: false
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
let(:dsl) { GQLi::DSL }
|
|
28
|
+
|
|
29
|
+
context 'validations enabled' do
|
|
30
|
+
subject { client }
|
|
31
|
+
|
|
32
|
+
it 'upon instantiation caches the schema' do
|
|
33
|
+
expect(subject.schema.types).not_to be_empty
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'when executing a query performs schema validation' do
|
|
37
|
+
vcr('catCollection') {
|
|
38
|
+
expect(subject.execute(
|
|
39
|
+
dsl.query {
|
|
40
|
+
catCollection {
|
|
41
|
+
items {
|
|
42
|
+
name
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}).data
|
|
46
|
+
).not_to be_empty
|
|
47
|
+
|
|
48
|
+
expect { subject.execute(
|
|
49
|
+
dsl.query {
|
|
50
|
+
foobar
|
|
51
|
+
}
|
|
52
|
+
)}.to raise_exception 'Validation Error: query is invalid - HTTP Request not sent'
|
|
53
|
+
}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'can skip validations when using `#execute!`' do
|
|
57
|
+
vcr('validation_error') {
|
|
58
|
+
expect { subject.execute!(
|
|
59
|
+
dsl.query {
|
|
60
|
+
foobar
|
|
61
|
+
}
|
|
62
|
+
)}.to raise_exception([
|
|
63
|
+
"Error: Bad Request",
|
|
64
|
+
'Body: {"errors":[{"message":"Cannot query field \"foobar\" on type \"Query\".","locations":[{"line":2,"column":3}]}]}'
|
|
65
|
+
].join("\n"))
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
context 'validations disabled' do
|
|
71
|
+
subject { client_no_validations }
|
|
72
|
+
|
|
73
|
+
it 'upon instantiation doesnt cache the schema' do
|
|
74
|
+
expect(subject.schema).to be_nil
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'when executing a query doesnt perform schema validation' do
|
|
78
|
+
vcr('validation_error') {
|
|
79
|
+
expect { subject.execute(
|
|
80
|
+
dsl.query {
|
|
81
|
+
foobar
|
|
82
|
+
}
|
|
83
|
+
)}.to raise_exception([
|
|
84
|
+
"Error: Bad Request",
|
|
85
|
+
'Body: {"errors":[{"message":"Cannot query field \"foobar\" on type \"Query\".","locations":[{"line":2,"column":3}]}]}'
|
|
86
|
+
].join("\n"))
|
|
87
|
+
}
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
class MockGQLInterface
|
|
4
|
+
include GQLi::DSL
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
describe GQLi::DSL do
|
|
8
|
+
subject { described_class }
|
|
9
|
+
|
|
10
|
+
describe 'module level methods' do
|
|
11
|
+
describe '::query' do
|
|
12
|
+
it 'can create a query without name' do
|
|
13
|
+
query = subject.query {
|
|
14
|
+
someField
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
expect(query).to be_a GQLi::Query
|
|
18
|
+
expect(query.to_gql).to eq <<~GRAPHQL
|
|
19
|
+
query {
|
|
20
|
+
someField
|
|
21
|
+
}
|
|
22
|
+
GRAPHQL
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'can create a query with a name' do
|
|
26
|
+
query = subject.query('FooBar') {
|
|
27
|
+
someOtherField
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
expect(query).to be_a GQLi::Query
|
|
31
|
+
expect(query.to_gql).to eq <<~GRAPHQL
|
|
32
|
+
query FooBar {
|
|
33
|
+
someOtherField
|
|
34
|
+
}
|
|
35
|
+
GRAPHQL
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe '::fragment' do
|
|
40
|
+
it 'can create a fragment' do
|
|
41
|
+
fragment = subject.fragment('FooBar', 'Foo') {
|
|
42
|
+
someFooField
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
expect(fragment).to be_a GQLi::Fragment
|
|
46
|
+
expect(fragment.to_gql).to eq <<~GRAPHQL
|
|
47
|
+
fragment FooBar on Foo {
|
|
48
|
+
someFooField
|
|
49
|
+
}
|
|
50
|
+
GRAPHQL
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe 'instance level methods' do
|
|
56
|
+
subject { MockGQLInterface.new }
|
|
57
|
+
|
|
58
|
+
describe '#query does the same as ::query' do
|
|
59
|
+
it 'can create a query without name' do
|
|
60
|
+
query = subject.query {
|
|
61
|
+
someField
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
expect(query).to be_a GQLi::Query
|
|
65
|
+
expect(query.to_gql).to eq <<~GRAPHQL
|
|
66
|
+
query {
|
|
67
|
+
someField
|
|
68
|
+
}
|
|
69
|
+
GRAPHQL
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'can create a query with a name' do
|
|
73
|
+
query = subject.query('FooBar') {
|
|
74
|
+
someOtherField
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
expect(query).to be_a GQLi::Query
|
|
78
|
+
expect(query.to_gql).to eq <<~GRAPHQL
|
|
79
|
+
query FooBar {
|
|
80
|
+
someOtherField
|
|
81
|
+
}
|
|
82
|
+
GRAPHQL
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
describe '#fragment does the same as ::fragment' do
|
|
87
|
+
it 'can create a fragment' do
|
|
88
|
+
fragment = subject.fragment('FooBar', 'Foo') {
|
|
89
|
+
someFooField
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
expect(fragment).to be_a GQLi::Fragment
|
|
93
|
+
expect(fragment.to_gql).to eq <<~GRAPHQL
|
|
94
|
+
fragment FooBar on Foo {
|
|
95
|
+
someFooField
|
|
96
|
+
}
|
|
97
|
+
GRAPHQL
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
describe 'node DSL' do
|
|
103
|
+
it 'nodes can have arguments' do
|
|
104
|
+
query = subject.query {
|
|
105
|
+
someNode(arg1: 100)
|
|
106
|
+
otherNode(arg2: 'some_string')
|
|
107
|
+
moreNodes(arg3: { nestedArg: [1, 2] })
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
expect(query.to_gql).to eq <<~GRAPHQL
|
|
111
|
+
query {
|
|
112
|
+
someNode(arg1: 100)
|
|
113
|
+
otherNode(arg2: "some_string")
|
|
114
|
+
moreNodes(arg3: {nestedArg: [1, 2]})
|
|
115
|
+
}
|
|
116
|
+
GRAPHQL
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it 'nodes can have arbitrarily nested nodes' do
|
|
120
|
+
query = subject.query {
|
|
121
|
+
aNode {
|
|
122
|
+
withChild {
|
|
123
|
+
moreChildren
|
|
124
|
+
andASibiling(someParameterHere: 'just for fun') {
|
|
125
|
+
withEvenMore
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
alsoASibiling
|
|
129
|
+
}
|
|
130
|
+
withoutChild
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
expect(query.to_gql).to eq <<~GRAPHQL
|
|
134
|
+
query {
|
|
135
|
+
aNode {
|
|
136
|
+
withChild {
|
|
137
|
+
moreChildren
|
|
138
|
+
andASibiling(someParameterHere: "just for fun") {
|
|
139
|
+
withEvenMore
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
alsoASibiling
|
|
143
|
+
}
|
|
144
|
+
withoutChild
|
|
145
|
+
}
|
|
146
|
+
GRAPHQL
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it 'queries can have inlined fragments at any level' do
|
|
150
|
+
NameFragment = subject.fragment('NameFragment', 'Foo') {
|
|
151
|
+
name
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
AgeFragment = subject.fragment('AgeFragment', 'Foo') {
|
|
155
|
+
age
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
query = subject.query {
|
|
159
|
+
peopleCollection {
|
|
160
|
+
___ NameFragment
|
|
161
|
+
___ AgeFragment
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
expect(query.to_gql).to eq <<~GRAPHQL
|
|
166
|
+
query {
|
|
167
|
+
peopleCollection {
|
|
168
|
+
name
|
|
169
|
+
age
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
GRAPHQL
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it 'queries can have type matchers' do
|
|
176
|
+
query = subject.query {
|
|
177
|
+
catCollection {
|
|
178
|
+
items {
|
|
179
|
+
name
|
|
180
|
+
bestFriend {
|
|
181
|
+
__on('Cat') {
|
|
182
|
+
name
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
expect(query.to_gql).to eq <<~GRAPHQL
|
|
190
|
+
query {
|
|
191
|
+
catCollection {
|
|
192
|
+
items {
|
|
193
|
+
name
|
|
194
|
+
bestFriend {
|
|
195
|
+
... on Cat {
|
|
196
|
+
name
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
GRAPHQL
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe GQLi::Introspection do
|
|
4
|
+
let(:dsl) { GQLi::DSL }
|
|
5
|
+
let(:client) do
|
|
6
|
+
vcr('client') {
|
|
7
|
+
space_id = 'cfexampleapi'
|
|
8
|
+
token = 'b4c0n73n7fu1'
|
|
9
|
+
GQLi::Client.new(
|
|
10
|
+
"https://graphql.contentful.com/content/v1/spaces/#{space_id}",
|
|
11
|
+
headers: { "Authorization" => "Bearer #{token}" }
|
|
12
|
+
)
|
|
13
|
+
}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
subject { client.schema }
|
|
17
|
+
|
|
18
|
+
describe 'introspection schema' do
|
|
19
|
+
it 'queries the API for the schema' do
|
|
20
|
+
expect(subject.types).not_to be_empty
|
|
21
|
+
|
|
22
|
+
expect(subject.types.map(&:name)).to include('Cat', 'CatCollection', 'Human')
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe 'validations' do
|
|
27
|
+
it 'valid query returns true' do
|
|
28
|
+
query = dsl.query {
|
|
29
|
+
catCollection(
|
|
30
|
+
locale:"en-US",
|
|
31
|
+
limit: 1,
|
|
32
|
+
where: {
|
|
33
|
+
name:"Nyan Cat",
|
|
34
|
+
OR: {
|
|
35
|
+
name:"Happy Cat"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
) {
|
|
39
|
+
items {
|
|
40
|
+
name
|
|
41
|
+
color
|
|
42
|
+
birthday
|
|
43
|
+
lives
|
|
44
|
+
bestFriend {
|
|
45
|
+
__on('Cat') {
|
|
46
|
+
name
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
image {
|
|
50
|
+
url
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
expect(subject.valid?(query)).to be_truthy
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'wrong node returns false' do
|
|
60
|
+
query = dsl.query {
|
|
61
|
+
foo
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
expect(subject.valid?(query)).to be_falsey
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'object node that doesnt have proper values returns false' do
|
|
68
|
+
query = dsl.query {
|
|
69
|
+
catCollection
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
expect(subject.valid?(query)).to be_falsey
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'object list node that doesnt have proper values returns false' do
|
|
76
|
+
query = dsl.query {
|
|
77
|
+
catCollection {
|
|
78
|
+
items
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
expect(subject.valid?(query)).to be_falsey
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'type matching on invalid type returns false' do
|
|
86
|
+
query = dsl.query {
|
|
87
|
+
catCollection {
|
|
88
|
+
items {
|
|
89
|
+
bestFriend {
|
|
90
|
+
__on('InvalidType') {
|
|
91
|
+
foo
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
expect(subject.valid?(query)).to be_falsey
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it 'invalid arguments return false' do
|
|
102
|
+
query = dsl.query {
|
|
103
|
+
catCollection(invalidParam: 1) {
|
|
104
|
+
items {
|
|
105
|
+
name
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
expect(subject.valid?(query)).to be_falsey
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it 'invalid argument type returns false' do
|
|
114
|
+
query = dsl.query {
|
|
115
|
+
catCollection(limit: 'foo') {
|
|
116
|
+
items {
|
|
117
|
+
name
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
expect(subject.valid?(query)).to be_falsey
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'simplecov'
|
|
2
|
+
SimpleCov.start
|
|
3
|
+
|
|
4
|
+
require 'rspec'
|
|
5
|
+
require 'vcr'
|
|
6
|
+
|
|
7
|
+
Dir[File.join('..', File.dirname(__FILE__), 'lib', '**', '*.rb')].each { |f| require f }
|
|
8
|
+
|
|
9
|
+
require 'gqli'
|
|
10
|
+
|
|
11
|
+
RSpec.configure do |config|
|
|
12
|
+
config.filter_run :focus => true
|
|
13
|
+
config.run_all_when_everything_filtered = true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
VCR.configure do |c|
|
|
17
|
+
c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
|
|
18
|
+
c.ignore_localhost = true
|
|
19
|
+
c.hook_into :webmock
|
|
20
|
+
c.default_cassette_options = { record: :once }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def vcr(name, &block)
|
|
24
|
+
VCR.use_cassette(name, &block)
|
|
25
|
+
end
|
data/usage.rb
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require_relative './lib/gqli'
|
|
2
|
+
|
|
3
|
+
puts GQLi::DSL.query {
|
|
4
|
+
__on('Foo') {
|
|
5
|
+
bar
|
|
6
|
+
}
|
|
7
|
+
}.to_gql
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
puts GQLi::DSL.query {
|
|
11
|
+
viewer {
|
|
12
|
+
login
|
|
13
|
+
repositories(first: 10) {
|
|
14
|
+
edges {
|
|
15
|
+
node {
|
|
16
|
+
nameWithOwner
|
|
17
|
+
watchers(first: 10) {
|
|
18
|
+
edges {
|
|
19
|
+
node {
|
|
20
|
+
login
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}.to_gql
|
|
29
|
+
|
|
30
|
+
FragmentFoo = GQLi::DSL.fragment('Foo', 'Bar') {
|
|
31
|
+
foo
|
|
32
|
+
bar(b: 10)
|
|
33
|
+
baz {
|
|
34
|
+
qux(c: 3)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
puts FragmentFoo.to_gql
|
|
39
|
+
|
|
40
|
+
puts GQLi::DSL.query {
|
|
41
|
+
___ FragmentFoo
|
|
42
|
+
}.to_gql
|
|
43
|
+
|
|
44
|
+
puts "-------------"
|
|
45
|
+
|
|
46
|
+
SPACE_ID = 'cfexampleapi'
|
|
47
|
+
ACCESS_TOKEN = 'b4c0n73n7fu1'
|
|
48
|
+
CONTENTFUL_GQL = GQLi::Client.new(
|
|
49
|
+
"https://graphql.contentful.com/content/v1/spaces/#{SPACE_ID}",
|
|
50
|
+
headers: { "Authorization" => "Bearer #{ACCESS_TOKEN}" }
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
CatBase = GQLi::DSL.fragment('CatBase', 'Cat') {
|
|
54
|
+
name
|
|
55
|
+
likes
|
|
56
|
+
lives
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
CatBestFriend = GQLi::DSL.fragment('CatBestFriend', 'Cat') {
|
|
60
|
+
bestFriend {
|
|
61
|
+
__on('Cat') {
|
|
62
|
+
___ CatBase
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
CatImportantFields = GQLi::DSL.fragment('CatImportantFields', 'Cat') {
|
|
68
|
+
___ CatBase
|
|
69
|
+
___ CatBestFriend
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
Query = GQLi::DSL.query {
|
|
73
|
+
catCollection(limit: 1) {
|
|
74
|
+
items {
|
|
75
|
+
___ CatImportantFields
|
|
76
|
+
image {
|
|
77
|
+
url
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
response = CONTENTFUL_GQL.execute(Query)
|
|
84
|
+
|
|
85
|
+
puts "Query sent:"
|
|
86
|
+
puts response.query.to_gql
|
|
87
|
+
|
|
88
|
+
puts
|
|
89
|
+
puts "Response received"
|
|
90
|
+
response.data.catCollection.items.each do |c|
|
|
91
|
+
puts "Name: #{c.nam}e"
|
|
92
|
+
puts "Likes: #{c.likes.join(", ")}"
|
|
93
|
+
puts "Lives #: #{c.lives}"
|
|
94
|
+
c.bestFriend.tap do |bf|
|
|
95
|
+
puts "Best Friend:"
|
|
96
|
+
puts "\tName: #{bf.name}"
|
|
97
|
+
puts "\tLikes: #{bf.likes.join(", ")}"
|
|
98
|
+
puts "\tLives #: #{bf.lives}"
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require_relative './lib/gqli'
|
|
2
|
+
|
|
3
|
+
SPACE_ID = 'cfexampleapi'
|
|
4
|
+
ACCESS_TOKEN = 'b4c0n73n7fu1'
|
|
5
|
+
CONTENTFUL_GQL = GQLi::Client.new(
|
|
6
|
+
"https://graphql.contentful.com/content/v1/spaces/#{SPACE_ID}",
|
|
7
|
+
headers: { "Authorization" => "Bearer #{ACCESS_TOKEN}" }
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
CatBase = GQLi::DSL.fragment('CatBase', 'Cat') {
|
|
11
|
+
name
|
|
12
|
+
likes
|
|
13
|
+
lives
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
CatBestFriend = GQLi::DSL.fragment('CatBestFriend', 'Cat') {
|
|
17
|
+
bestFriend {
|
|
18
|
+
__on('Cat') {
|
|
19
|
+
___ CatBase
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
CatImportantFields = GQLi::DSL.fragment('CatImportantFields', 'Cat') {
|
|
25
|
+
___ CatBase
|
|
26
|
+
___ CatBestFriend
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
Query = GQLi::DSL.query {
|
|
30
|
+
catCollection(limit: 1) {
|
|
31
|
+
items {
|
|
32
|
+
___ CatImportantFields
|
|
33
|
+
image {
|
|
34
|
+
url
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
response = CONTENTFUL_GQL.execute(Query)
|
|
41
|
+
|
|
42
|
+
puts "Query sent:"
|
|
43
|
+
puts response.query.to_gql
|
|
44
|
+
|
|
45
|
+
puts
|
|
46
|
+
puts "Response received"
|
|
47
|
+
response.data.catCollection.items.each do |c|
|
|
48
|
+
puts "Name: #{c.nam}e"
|
|
49
|
+
puts "Likes: #{c.likes.join(", ")}"
|
|
50
|
+
puts "Lives #: #{c.lives}"
|
|
51
|
+
c.bestFriend.tap do |bf|
|
|
52
|
+
puts "Best Friend:"
|
|
53
|
+
puts "\tName: #{bf.name}"
|
|
54
|
+
puts "\tLikes: #{bf.likes.join(", ")}"
|
|
55
|
+
puts "\tLives #: #{bf.lives}"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
puts "Trying to execute invalid query"
|
|
60
|
+
|
|
61
|
+
CONTENTFUL_GQL.execute!(GQLi::DSL.query {
|
|
62
|
+
invalidNode
|
|
63
|
+
})
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require_relative './lib/gqli'
|
|
2
|
+
|
|
3
|
+
class ContentfulClient
|
|
4
|
+
extend GQLi::DSL # Makes DSL available at a class level
|
|
5
|
+
include GQLi::DSL # Makes DSL available at an object level
|
|
6
|
+
|
|
7
|
+
SPACE_ID = 'cfexampleapi'
|
|
8
|
+
ACCESS_TOKEN = 'b4c0n73n7fu1'
|
|
9
|
+
CONTENTFUL_GQL = GQLi::Client.new(
|
|
10
|
+
"https://graphql.contentful.com/content/v1/spaces/#{SPACE_ID}",
|
|
11
|
+
headers: { "Authorization" => "Bearer #{ACCESS_TOKEN}" }
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
CatBase = fragment('CatBase', 'Cat') {
|
|
15
|
+
name
|
|
16
|
+
likes
|
|
17
|
+
lives
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
CatBestFriend = fragment('CatBestFriend', 'Cat') {
|
|
21
|
+
bestFriend {
|
|
22
|
+
__on('Cat') {
|
|
23
|
+
___ CatBase
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
CatImportantFields = fragment('CatImportantFields', 'Cat') {
|
|
29
|
+
___ CatBase
|
|
30
|
+
___ CatBestFriend
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
def cats
|
|
34
|
+
CONTENTFUL_GQL.execute(
|
|
35
|
+
query {
|
|
36
|
+
catCollection(limit: 10, locale: 'tlh') {
|
|
37
|
+
items {
|
|
38
|
+
___ CatImportantFields
|
|
39
|
+
image {
|
|
40
|
+
url
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
response = ContentfulClient.new.cats
|
|
50
|
+
|
|
51
|
+
puts "Query sent:"
|
|
52
|
+
puts response.query.to_gql
|
|
53
|
+
|
|
54
|
+
puts
|
|
55
|
+
puts "Response received"
|
|
56
|
+
response.data.catCollection.items.each do |c|
|
|
57
|
+
puts "Name: #{c.name}"
|
|
58
|
+
puts "Likes: #{c.likes.join(", ")}"
|
|
59
|
+
puts "Lives #: #{c.lives}"
|
|
60
|
+
puts "Image: #{c.image.url}" if c.image?
|
|
61
|
+
c.bestFriend.tap do |bf|
|
|
62
|
+
next if bf.nil?
|
|
63
|
+
puts "Best Friend:"
|
|
64
|
+
puts "\tName: #{bf.name}"
|
|
65
|
+
puts "\tLikes: #{bf.likes.join(", ")}"
|
|
66
|
+
puts "\tLives #: #{bf.lives}"
|
|
67
|
+
end
|
|
68
|
+
puts
|
|
69
|
+
end
|