gqli 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/gqli/client.rb +23 -5
- data/lib/gqli/clients/contentful.rb +3 -2
- data/lib/gqli/response.rb +15 -2
- data/lib/gqli/version.rb +1 -1
- data/spec/lib/gqli/client_spec.rb +53 -0
- data/spec/lib/gqli/response_spec.rb +51 -0
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4315f21be8d0b00907f0310acc1a17f300dd9157874bf09c75e577ef3b7fb95
|
4
|
+
data.tar.gz: e51cda712da56a947079aa807610bf0979352d3b2e3c2ed28eba337051df85d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71560b1443fc3487f6de643950683b1a5b635cc35f3431d4af36379a29bee58308f20a19037e484065fc43790071574d62068c38c960268b2a55eb37232b8617
|
7
|
+
data.tar.gz: 2d94bff9408e828967ee3b7e20f980a59dc536f4a579675fa8d909149fd908fa8a55d2f2b7022552afc3e3ac644c5472003bedcb21249b6b959add3b2257269f
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## v1.1.0
|
6
|
+
* Added support for timeout management. [#11](https://github.com/contentful-labs/gqli.rb/pull/11)
|
7
|
+
* Added support for error response handling. [#13](https://github.com/contentful-labs/gqli.rb/pull/13)
|
8
|
+
|
5
9
|
## v1.0.0
|
6
10
|
### Added
|
7
11
|
* Added support for Mutations.
|
data/lib/gqli/client.rb
CHANGED
@@ -9,13 +9,17 @@ require_relative './version'
|
|
9
9
|
module GQLi
|
10
10
|
# GraphQL HTTP Client
|
11
11
|
class Client
|
12
|
-
attr_reader :url, :params, :headers, :validate_query, :schema
|
12
|
+
attr_reader :url, :params, :headers, :validate_query, :schema, :options
|
13
13
|
|
14
|
-
def initialize(url, params: {}, headers: {}, validate_query: true)
|
14
|
+
def initialize(url, params: {}, headers: {}, validate_query: true, options: {})
|
15
15
|
@url = url
|
16
16
|
@params = params
|
17
17
|
@headers = headers
|
18
18
|
@validate_query = validate_query
|
19
|
+
@options = options
|
20
|
+
@options[:read_timeout] ||= 60
|
21
|
+
@options[:write_timeout] ||= 60
|
22
|
+
@options[:connect_timeout] ||= 60
|
19
23
|
|
20
24
|
@schema = Introspection.new(self) if validate_query
|
21
25
|
end
|
@@ -34,13 +38,15 @@ module GQLi
|
|
34
38
|
# Executres a query
|
35
39
|
# Ignores validations
|
36
40
|
def execute!(query)
|
37
|
-
http_response =
|
41
|
+
http_response = request.post(@url, params: @params, json: { query: query.to_gql })
|
38
42
|
|
39
43
|
fail "Error: #{http_response.reason}\nBody: #{http_response.body}" if http_response.status >= 300
|
40
44
|
|
41
|
-
|
45
|
+
parsed_response = JSON.parse(http_response.to_s)
|
46
|
+
data = parsed_response['data']
|
47
|
+
errors = parsed_response['errors']
|
42
48
|
|
43
|
-
Response.new(data, query)
|
49
|
+
Response.new(data, errors, query)
|
44
50
|
end
|
45
51
|
|
46
52
|
# Validates a query against the schema
|
@@ -50,6 +56,10 @@ module GQLi
|
|
50
56
|
schema.valid?(query)
|
51
57
|
end
|
52
58
|
|
59
|
+
def request
|
60
|
+
HTTP.headers(request_headers).timeout(timeout_options)
|
61
|
+
end
|
62
|
+
|
53
63
|
protected
|
54
64
|
|
55
65
|
def validation_error_message(validation)
|
@@ -67,5 +77,13 @@ module GQLi
|
|
67
77
|
user_agent: "gqli.rb/#{VERSION}; http.rb/#{HTTP::VERSION}"
|
68
78
|
}.merge(@headers)
|
69
79
|
end
|
80
|
+
|
81
|
+
def timeout_options
|
82
|
+
{
|
83
|
+
write: options[:write_timeout],
|
84
|
+
connect: options[:connect_timeout],
|
85
|
+
read: options[:read_timeout]
|
86
|
+
}
|
87
|
+
end
|
70
88
|
end
|
71
89
|
end
|
@@ -4,7 +4,7 @@ module GQLi
|
|
4
4
|
# Module for creating a Contentful GraphQL client
|
5
5
|
module Contentful
|
6
6
|
# Creates a Contentful GraphQL client
|
7
|
-
def self.create(space, access_token, environment: nil, validate_query: true)
|
7
|
+
def self.create(space, access_token, environment: nil, validate_query: true, options: {})
|
8
8
|
api_url = "https://graphql.contentful.com/content/v1/spaces/#{space}"
|
9
9
|
api_url += "/environments/#{environment}" unless environment.nil?
|
10
10
|
|
@@ -13,7 +13,8 @@ module GQLi
|
|
13
13
|
headers: {
|
14
14
|
'Authorization' => "Bearer #{access_token}"
|
15
15
|
},
|
16
|
-
validate_query: validate_query
|
16
|
+
validate_query: validate_query,
|
17
|
+
options: options
|
17
18
|
)
|
18
19
|
end
|
19
20
|
end
|
data/lib/gqli/response.rb
CHANGED
@@ -5,11 +5,24 @@ require 'hashie/mash'
|
|
5
5
|
module GQLi
|
6
6
|
# Response object wrapper
|
7
7
|
class Response
|
8
|
-
attr_reader :data, :query
|
8
|
+
attr_reader :data, :errors, :query
|
9
9
|
|
10
|
-
def initialize(data, query)
|
10
|
+
def initialize(data, errors, query)
|
11
11
|
@data = Hashie::Mash.new(data)
|
12
|
+
@errors = parse_errors(errors)
|
12
13
|
@query = query
|
13
14
|
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# Accepts Hash or Array of errors and converts them to Hashie::Mash instances.
|
19
|
+
# Recursively calls #parse_errors with items if array.
|
20
|
+
# Returns nil if nil is passed.
|
21
|
+
def parse_errors(errors)
|
22
|
+
return unless errors
|
23
|
+
return errors.map { |e| parse_errors(e) } if errors.is_a?(Array)
|
24
|
+
|
25
|
+
Hashie::Mash.new(errors)
|
26
|
+
end
|
14
27
|
end
|
15
28
|
end
|
data/lib/gqli/version.rb
CHANGED
@@ -3,6 +3,8 @@ require 'spec_helper'
|
|
3
3
|
describe GQLi::Client do
|
4
4
|
let(:space_id) { 'cfexampleapi' }
|
5
5
|
let(:token) { 'b4c0n73n7fu1' }
|
6
|
+
let(:default_timeout) { 60 }
|
7
|
+
let(:timeout) { 10 }
|
6
8
|
|
7
9
|
let(:client) do
|
8
10
|
vcr('client') {
|
@@ -20,6 +22,21 @@ describe GQLi::Client do
|
|
20
22
|
}
|
21
23
|
end
|
22
24
|
|
25
|
+
let(:client_with_timeout) do
|
26
|
+
vcr('client') {
|
27
|
+
GQLi::Contentful.create(
|
28
|
+
space_id,
|
29
|
+
token,
|
30
|
+
validate_query: false,
|
31
|
+
options: {
|
32
|
+
connect_timeout: timeout,
|
33
|
+
read_timeout: timeout,
|
34
|
+
write_timeout: timeout
|
35
|
+
}
|
36
|
+
)
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
23
40
|
let(:dsl) { GQLi::DSL }
|
24
41
|
|
25
42
|
describe 'default clients' do
|
@@ -118,4 +135,40 @@ describe GQLi::Client do
|
|
118
135
|
}
|
119
136
|
end
|
120
137
|
end
|
138
|
+
|
139
|
+
context 'without timeout options' do
|
140
|
+
subject { client }
|
141
|
+
|
142
|
+
it 'upon instantiation sets default timeout value' do
|
143
|
+
expect(subject.options[:read_timeout]).to eq(default_timeout)
|
144
|
+
expect(subject.options[:connect_timeout]).to eq(default_timeout)
|
145
|
+
expect(subject.options[:write_timeout]).to eq(default_timeout)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'when executing a request sets default timeout value' do
|
149
|
+
expect(subject.request.default_options.timeout_options[:read_timeout]).to eq(default_timeout)
|
150
|
+
expect(subject.request.default_options.timeout_options[:connect_timeout]).to eq(default_timeout)
|
151
|
+
expect(subject.request.default_options.timeout_options[:write_timeout]).to eq(default_timeout)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context 'with timeout options' do
|
156
|
+
subject { client_with_timeout }
|
157
|
+
|
158
|
+
it 'contentful client' do
|
159
|
+
expect(subject).to be_a(GQLi::Client)
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'upon instantiation sets provided timeout value' do
|
163
|
+
expect(subject.options[:read_timeout]).to eq(timeout)
|
164
|
+
expect(subject.options[:connect_timeout]).to eq(timeout)
|
165
|
+
expect(subject.options[:write_timeout]).to eq(timeout)
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'when executing a request sets provided timeout value' do
|
169
|
+
expect(subject.request.default_options.timeout_options[:read_timeout]).to eq(timeout)
|
170
|
+
expect(subject.request.default_options.timeout_options[:connect_timeout]).to eq(timeout)
|
171
|
+
expect(subject.request.default_options.timeout_options[:write_timeout]).to eq(timeout)
|
172
|
+
end
|
173
|
+
end
|
121
174
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GQLi::Response do
|
4
|
+
let(:errors) { nil }
|
5
|
+
let(:data) { {"testkey" => "test val"} }
|
6
|
+
let(:query) { double(:query) }
|
7
|
+
subject { described_class.new(data, errors, query) }
|
8
|
+
|
9
|
+
describe "#data" do
|
10
|
+
it "returns correct data Hashie" do
|
11
|
+
expect(subject.data).to be_kind_of(Hashie::Mash)
|
12
|
+
expect(subject.data.testkey).to eq(data["testkey"])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#query" do
|
17
|
+
it "returns correct query" do
|
18
|
+
expect(subject.query).to eq(query)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#errors" do
|
23
|
+
context "array errors" do
|
24
|
+
let(:errors) { [{"message" => "this is an error"}] }
|
25
|
+
|
26
|
+
it "converts errors to correct Hashie instances" do
|
27
|
+
expect(subject.errors).to be_kind_of(Array)
|
28
|
+
expect(subject.errors.length).to eq(1)
|
29
|
+
expect(subject.errors.first).to be_kind_of(Hashie::Mash)
|
30
|
+
expect(subject.errors.first.message).to eq(errors.first["message"])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "hash errors" do
|
35
|
+
let(:errors) { {"message" => "this is an error"} }
|
36
|
+
|
37
|
+
it "converts errors to correct Hashie instances" do
|
38
|
+
expect(subject.errors).to be_kind_of(Hashie::Mash)
|
39
|
+
expect(subject.errors.message).to eq(errors["message"])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "nil errors" do
|
44
|
+
it "does not raise error and returns nil" do
|
45
|
+
expect(subject.errors).to be(nil)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gqli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Contentful GmbH (David Litvak Bruno)
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http
|
@@ -349,6 +349,7 @@ files:
|
|
349
349
|
- spec/lib/gqli/client_spec.rb
|
350
350
|
- spec/lib/gqli/dsl_spec.rb
|
351
351
|
- spec/lib/gqli/introspection_spec.rb
|
352
|
+
- spec/lib/gqli/response_spec.rb
|
352
353
|
- spec/spec_helper.rb
|
353
354
|
- usage.rb
|
354
355
|
- usage_introspection.rb
|
@@ -357,7 +358,7 @@ homepage: https://github.com/contentful-labs/gqli.rb
|
|
357
358
|
licenses:
|
358
359
|
- MIT
|
359
360
|
metadata: {}
|
360
|
-
post_install_message:
|
361
|
+
post_install_message:
|
361
362
|
rdoc_options: []
|
362
363
|
require_paths:
|
363
364
|
- lib
|
@@ -373,7 +374,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
373
374
|
version: '0'
|
374
375
|
requirements: []
|
375
376
|
rubygems_version: 3.0.3
|
376
|
-
signing_key:
|
377
|
+
signing_key:
|
377
378
|
specification_version: 4
|
378
379
|
summary: GraphQL client for humans
|
379
380
|
test_files:
|
@@ -384,4 +385,5 @@ test_files:
|
|
384
385
|
- spec/lib/gqli/client_spec.rb
|
385
386
|
- spec/lib/gqli/dsl_spec.rb
|
386
387
|
- spec/lib/gqli/introspection_spec.rb
|
388
|
+
- spec/lib/gqli/response_spec.rb
|
387
389
|
- spec/spec_helper.rb
|