gqli 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|