graphlient 0.5.0 → 0.7.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 +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/ci.yml +29 -0
- data/.github/workflows/danger.yml +22 -0
- data/.github/workflows/rubocop.yml +19 -0
- data/CHANGELOG.md +32 -19
- data/Dangerfile +24 -1
- data/Gemfile +1 -1
- data/Gemfile.danger +5 -0
- data/README.md +72 -2
- data/graphlient.gemspec +1 -2
- data/lib/graphlient/adapters/http/faraday_adapter.rb +0 -1
- data/lib/graphlient/client.rb +1 -1
- data/lib/graphlient/query.rb +21 -2
- data/lib/graphlient/version.rb +1 -1
- data/spec/graphlient/adapters/http/faraday_adapter_spec.rb +4 -4
- data/spec/graphlient/client_query_spec.rb +70 -3
- data/spec/graphlient/client_schema_spec.rb +13 -3
- data/spec/graphlient/schema_spec.rb +4 -1
- data/spec/graphlient/webmock_client_query_spec.rb +2 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/support/mutations/create_invoice.rb +1 -0
- data/spec/support/queries/query.rb +23 -0
- data/spec/support/types/invoice_type.rb +6 -0
- metadata +13 -22
- data/.travis.yml +0 -24
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aa3b9416b7374b0c3881224177f2a5646432e27ce9fcfdb2454b31ba318e231a
|
|
4
|
+
data.tar.gz: 6ca64471c0129dc021248fa309ed187bde0c9f9e58cf07a98d9072768e5446fe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f035b28bfd747c72574b124cd5130e92798ac6b14d9000b73c6ce25357489f23ded22ca11dd74cc777c96dfeada948f86a9dd3b754838abf230cf82849e8f893
|
|
7
|
+
data.tar.gz: e6fd794359759c72051ddd7114fbe85c1110d0b743f55cd521cdcbb56fc9e6cecd4a70b6a6383f76d5304fd542d889e965d28738394995282768794059067b6c
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Create a report to help us improve
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Describe the bug**
|
|
11
|
+
A clear and concise description of what the bug is.
|
|
12
|
+
|
|
13
|
+
**To Reproduce**
|
|
14
|
+
Steps to reproduce the behavior:
|
|
15
|
+
1. Go to '...'
|
|
16
|
+
2. Click on '....'
|
|
17
|
+
3. Scroll down to '....'
|
|
18
|
+
4. See error
|
|
19
|
+
|
|
20
|
+
**Expected behavior**
|
|
21
|
+
A clear and concise description of what you expected to happen.
|
|
22
|
+
|
|
23
|
+
**Screenshots**
|
|
24
|
+
If applicable, add screenshots to help explain your problem.
|
|
25
|
+
|
|
26
|
+
**Desktop (please complete the following information):**
|
|
27
|
+
- OS: [e.g. iOS]
|
|
28
|
+
- Browser [e.g. chrome, safari]
|
|
29
|
+
- Version [e.g. 22]
|
|
30
|
+
|
|
31
|
+
**Smartphone (please complete the following information):**
|
|
32
|
+
- Device: [e.g. iPhone6]
|
|
33
|
+
- OS: [e.g. iOS8.1]
|
|
34
|
+
- Browser [e.g. stock browser, safari]
|
|
35
|
+
- Version [e.g. 22]
|
|
36
|
+
|
|
37
|
+
**Additional context**
|
|
38
|
+
Add any other context about the problem here.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest an idea for this project
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Is your feature request related to a problem? Please describe.**
|
|
11
|
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
|
12
|
+
|
|
13
|
+
**Describe the solution you'd like**
|
|
14
|
+
A clear and concise description of what you want to happen.
|
|
15
|
+
|
|
16
|
+
**Describe alternatives you've considered**
|
|
17
|
+
A clear and concise description of any alternative solutions or features you've considered.
|
|
18
|
+
|
|
19
|
+
**Additional context**
|
|
20
|
+
Add any other context or screenshots about the feature request here.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
entry:
|
|
14
|
+
- { ruby: 2.7.2 }
|
|
15
|
+
- { ruby: 3.0.0 }
|
|
16
|
+
- { ruby: 3.1.2 }
|
|
17
|
+
- { ruby: "ruby-head", ignore: true }
|
|
18
|
+
- { ruby: "jruby-9.1.17", ignore: true }
|
|
19
|
+
- { ruby: "jruby-head", ignore: true }
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v3
|
|
22
|
+
- name: Set up Ruby
|
|
23
|
+
uses: ruby/setup-ruby@v1
|
|
24
|
+
with:
|
|
25
|
+
ruby-version: ${{ matrix.entry.ruby }}
|
|
26
|
+
bundler-cache: true
|
|
27
|
+
- name: Run tests
|
|
28
|
+
continue-on-error: ${{ matrix.entry.ignore || false }}
|
|
29
|
+
run: bundle exec rspec spec/
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: Danger
|
|
2
|
+
|
|
3
|
+
on: pull_request
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
danger:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
env:
|
|
9
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/Gemfile.danger
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v3
|
|
12
|
+
with:
|
|
13
|
+
fetch-depth: 0
|
|
14
|
+
- name: Set up Ruby
|
|
15
|
+
uses: ruby/setup-ruby@v1
|
|
16
|
+
with:
|
|
17
|
+
ruby-version: 2.7.2
|
|
18
|
+
bundler-cache: true
|
|
19
|
+
- run: |
|
|
20
|
+
# the personal token is public, this is ok, base64 encode to avoid tripping Github
|
|
21
|
+
TOKEN=$(echo -n NWY1ZmM5MzEyMzNlYWY4OTZiOGU3MmI3MWQ3Mzk0MzgxMWE4OGVmYwo= | base64 --decode)
|
|
22
|
+
DANGER_GITHUB_API_TOKEN=$TOKEN bundle exec danger --verbose
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: Rubocop
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
rubocop:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v3
|
|
13
|
+
- name: Set up Ruby
|
|
14
|
+
uses: ruby/setup-ruby@v1
|
|
15
|
+
with:
|
|
16
|
+
ruby-version: 2.7.2
|
|
17
|
+
bundler-cache: true
|
|
18
|
+
- name: Run rubocop
|
|
19
|
+
run: bundle exec rubocop
|
data/CHANGELOG.md
CHANGED
|
@@ -1,74 +1,87 @@
|
|
|
1
|
-
###
|
|
1
|
+
### (Next)
|
|
2
2
|
* Your contribution here.
|
|
3
3
|
|
|
4
|
-
### 0.
|
|
4
|
+
### 0.7.0 (2022/10/11)
|
|
5
|
+
* [#98](https://github.com/ashkan18/graphlient/pull/98): Bring back danger checks and improve them - [@ashkan18](https://github.com/ashkan18).
|
|
6
|
+
* [#94](https://github.com/ashkan18/graphlient/pull/94): Enabled fragments - [@rellampec](https://github.com/rellampec).
|
|
7
|
+
* [#95](https://github.com/ashkan18/graphlient/pull/95): Upgrade faraday dependency to version 2 - [@kirillkaiumov](https://github.com/kirillkaiumov).
|
|
8
|
+
|
|
9
|
+
### 0.6.0 (2022/06/11)
|
|
10
|
+
|
|
11
|
+
* [#87](https://github.com/ashkan18/graphlient/pull/87): Raised `ExecutionError` with partial error response - [@QQism](https://github.com/QQism).
|
|
12
|
+
* [#90](https://github.com/ashkan18/graphlient/pull/90): Added support for Ruby 3.1 - [@QQism](https://github.com/QQism).
|
|
13
|
+
* [#90](https://github.com/ashkan18/graphlient/pull/90): Dropped support for Ruby 2.5 - [@QQism](https://github.com/QQism).
|
|
14
|
+
* [#91](https://github.com/ashkan18/graphlient/pull/91): Update GHA for `danger` with right permissions - [@QQism](https://github.com/QQism).
|
|
15
|
+
* [#89](https://github.com/ashkan18/graphlient/pull/89): Replace Travis CI with Github Actions - [@QQism](https://github.com/QQism).
|
|
16
|
+
|
|
17
|
+
### 0.5.0 (2020/12/28)
|
|
5
18
|
|
|
6
19
|
* [#81](https://github.com/ashkan18/graphlient/pull/81): Make graphlient run on ruby 3.0 - [@Burgestrand](https://github.com/Burgestrand).
|
|
7
20
|
* [#79](https://github.com/ashkan18/graphlient/pull/79): Added client testing docs - [@GabrielDzul](https://github.com/GabrielDzul).
|
|
8
21
|
|
|
9
|
-
### 0.4.0 (
|
|
22
|
+
### 0.4.0 (2020/05/22)
|
|
10
23
|
|
|
11
24
|
* [#72](https://github.com/ashkan18/graphlient/pull/72): Add http_options - [@neroleung](https://github.com/neroleung).
|
|
12
25
|
* [#71](https://github.com/ashkan18/graphlient/issues/70): Add `Graphlient::Errors::TimeoutError` - [@BenDrozdoff](https://github.com/BenDrozdoff).
|
|
13
26
|
* [#75](https://github.com/ashkan18/graphlient/pull/75): Support Faraday 1.x - [@jfhinchcliffe](https://github.com/jfhinchcliffe).
|
|
14
27
|
* [#78](https://github.com/ashkan18/graphlient/pull/78): Add description of timeout values - [@sap1enza](https://github.com/sap1enza).
|
|
15
28
|
|
|
16
|
-
### 0.3.7 (11/14
|
|
29
|
+
### 0.3.7 (2019/11/14)
|
|
17
30
|
|
|
18
31
|
* [#68](https://github.com/ashkan18/graphlient/pull/68): Add `Graphlient::Errors::ConnectionFailedError` - [@neroleung](https://github.com/neroleung).
|
|
19
32
|
|
|
20
|
-
### 0.3.6 (07/23
|
|
33
|
+
### 0.3.6 (2019/07/23)
|
|
21
34
|
|
|
22
35
|
* [#63](https://github.com/ashkan18/graphlient/pull/63): Remove unused method for attribute with typo - [@ashkan18](https://github.com/ashkan18).
|
|
23
36
|
* [#62](https://github.com/ashkan18/graphlient/pull/62): Fix typo preventing access to response object on error - [@jmondo](https://github.com/jmondo).
|
|
24
37
|
|
|
25
|
-
### 0.3.4 (01/31
|
|
38
|
+
### 0.3.4 (2019/01/31)
|
|
26
39
|
|
|
27
40
|
* [#56](https://github.com/ashkan18/graphlient/pull/56): Remove safe navigation usage to retain support for Ruby 2.2 - [@avinoth](https://github.com/avinoth).
|
|
28
41
|
* [#57](https://github.com/ashkan18/graphlient/pull/57): Add support for parsing queries from a String - [@ateamlunchbox](https://github.com/ateamlunchbox).
|
|
29
42
|
|
|
30
|
-
### 0.3.3 (09/23
|
|
43
|
+
### 0.3.3 (2018/09/23)
|
|
31
44
|
|
|
32
45
|
* [#50](https://github.com/ashkan18/graphlient/pull/50): More detailed error responses - [@ashkan18](https://github.com/ashkan18).
|
|
33
46
|
|
|
34
|
-
### 0.3.2 (07/03
|
|
47
|
+
### 0.3.2 (2018/07/03)
|
|
35
48
|
|
|
36
49
|
* [#46](https://github.com/ashkan18/graphlient/pull/46): Fix issue with gathering error details when trying `to_s` on `GraphQLError` - [@ashkan18](https://github.com/ashkan18).
|
|
37
50
|
* [#45](https://github.com/ashkan18/graphlient/pull/45): Drop Support for Ruby 2.2 and Lock RuboCop - [@jonallured](https://github.com/jonallured).
|
|
38
51
|
|
|
39
|
-
### 0.3.1 (04/17
|
|
52
|
+
### 0.3.1 (2018/04/17)
|
|
40
53
|
|
|
41
54
|
* [#43](https://github.com/ashkan18/graphlient/pull/43): Allow to load and dump schema to json - [@povilasjurcys](https://github.com/povilasjurcys).
|
|
42
55
|
|
|
43
|
-
### 0.3.0 (02/22
|
|
56
|
+
### 0.3.0 (2018/02/22)
|
|
44
57
|
|
|
45
58
|
* [#38](https://github.com/ashkan18/graphlient/pull/38): Add support for Ruby 2.5 - [@yuki24](https://github.com/yuki24).
|
|
46
59
|
* [#39](https://github.com/ashkan18/graphlient/pull/39): Add support for Ruby 2.2 - [@yuki24](https://github.com/yuki24).
|
|
47
60
|
* [#40](https://github.com/ashkan18/graphlient/pull/40): Add experimental support for JRuby - [@yuki24](https://github.com/yuki24).
|
|
48
61
|
|
|
49
|
-
### 0.2.0 (11/09
|
|
62
|
+
### 0.2.0 (2017/11/09)
|
|
50
63
|
|
|
51
64
|
* [#33](https://github.com/ashkan18/graphlient/pull/33): Added dsl for supporting parametrized queries/mutations - [@ashkan18](https://github.com/ashkan18).
|
|
52
65
|
* [#34](https://github.com/ashkan18/graphlient/issues/34): Fix: don't convert variables to `String` - [@dblock](https://github.com/dblock).
|
|
53
66
|
|
|
54
|
-
### 0.1.0 (10/27
|
|
67
|
+
### 0.1.0 (2017/10/27)
|
|
55
68
|
|
|
56
69
|
* [#31](https://github.com/ashkan18/graphlient/issues/31): Fix: catch execution errors that don't contain field names - [@dblock](https://github.com/dblock).
|
|
57
70
|
|
|
58
|
-
### 0.0.9 (10/26
|
|
71
|
+
### 0.0.9 (2017/10/26)
|
|
59
72
|
|
|
60
73
|
* [#28](https://github.com/ashkan18/graphlient/pull/28): Raise errors in `execute`, not only `query` - [@dblock](https://github.com/dblock).
|
|
61
74
|
* [#29](https://github.com/ashkan18/graphlient/pull/29): Added `Graphlient::Adapters::HTTP::HTTPAdapter` that replaces Faraday with `Net::HTTP` - [@dblock](https://github.com/dblock).
|
|
62
75
|
|
|
63
|
-
### 0.0.8 (10/26
|
|
76
|
+
### 0.0.8 (2017/10/26)
|
|
64
77
|
|
|
65
78
|
* [#27](https://github.com/ashkan18/graphlient/pull/27): Always raise an exception unless a query has succeeded - [@dblock](https://github.com/dblock).
|
|
66
79
|
|
|
67
|
-
### 0.0.7 (10/24
|
|
80
|
+
### 0.0.7 (2017/10/24)
|
|
68
81
|
|
|
69
82
|
* [#26](https://github.com/ashkan18/graphlient/pull/26): Support String queries - [@dblock](https://github.com/dblock).
|
|
70
83
|
|
|
71
|
-
### 0.0.6 (10/20
|
|
84
|
+
### 0.0.6 (2017/10/20)
|
|
72
85
|
|
|
73
86
|
* [#14](https://github.com/ashkan18/graphlient/pull/14): Switch to `graphql-client` for network calls and schema validation - [@ashkan18](https://github.com/ashkan18).
|
|
74
87
|
* [#17](https://github.com/ashkan18/graphlient/pull/17): Specialize server errors as `Graphlient::Errors::Server` - [@dblock](https://github.com/dblock).
|
|
@@ -79,16 +92,16 @@
|
|
|
79
92
|
* [#20](https://github.com/ashkan18/graphlient/pull/20): Added support for parameterized queries and mutations - [@dblock](https://github.com/dblock).
|
|
80
93
|
* [#25](https://github.com/ashkan18/graphlient/pull/25): Added `client.parse` and `client.execute` to parse and execute queries separately - [@dblock](https://github.com/dblock).
|
|
81
94
|
|
|
82
|
-
### 0.0.5 (10/
|
|
95
|
+
### 0.0.5 (2017/10/05)
|
|
83
96
|
|
|
84
97
|
* [#11](https://github.com/ashkan18/graphlient/pull/11): Fixed query argument types - [@ashkan18](https://github.com/ashkan18).
|
|
85
98
|
|
|
86
|
-
### 0.0.4 (10/
|
|
99
|
+
### 0.0.4 (2017/10/04)
|
|
87
100
|
|
|
88
101
|
* [#8](https://github.com/ashkan18/graphlient/pull/8): Handle HTTP errors and raise `Graphlient::Errors::HTTP` on failure - [@dblock](https://github.com/dblock).
|
|
89
102
|
* [#5](https://github.com/ashkan18/graphlient/pull/5): Added RuboCop, Ruby-style linter, CHANGELOG, CONTRIBUTING and RELEASING - [@dblock](https://github.com/dblock).
|
|
90
103
|
* [#4](https://github.com/ashkan18/graphlient/pull/4): Refactored Graphlient::Client to take a URL and options, moved extensions - [@dblock](https://github.com/dblock).
|
|
91
104
|
|
|
92
|
-
### 0.0.3 (10/
|
|
105
|
+
### 0.0.3 (2017/10/03)
|
|
93
106
|
|
|
94
107
|
* Initial public release - [@ashkan18](https://github.com/ashkan18).
|
data/Dangerfile
CHANGED
|
@@ -1 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
# Has any changes happened inside the actual library code?
|
|
5
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
6
|
+
has_app_changes = !git.modified_files.grep(/lib/).empty?
|
|
7
|
+
has_spec_changes = !git.modified_files.grep(/spec/).empty?
|
|
8
|
+
|
|
9
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
10
|
+
# You've made changes to lib, but didn't write any tests?
|
|
11
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
12
|
+
warn("There're library changes, but not tests. That's OK as long as you're refactoring existing code.", sticky: false) if has_app_changes && !has_spec_changes
|
|
13
|
+
|
|
14
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
15
|
+
# You've made changes to specs, but no library code has changed?
|
|
16
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
17
|
+
if !has_app_changes && has_spec_changes
|
|
18
|
+
message('We really appreciate pull requests that demonstrate issues, even without a fix. That said, the next step is to try and fix the failing tests!', sticky: false)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
22
|
+
# Have you updated CHANGELOG.md?
|
|
23
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
24
|
+
changelog.check!
|
data/Gemfile
CHANGED
|
@@ -10,11 +10,11 @@ end
|
|
|
10
10
|
|
|
11
11
|
group :development do
|
|
12
12
|
gem 'byebug', platform: :ruby
|
|
13
|
-
gem 'danger-changelog', '~> 0.2.1'
|
|
14
13
|
gem 'rubocop', '0.56.0'
|
|
15
14
|
end
|
|
16
15
|
|
|
17
16
|
group :test do
|
|
17
|
+
gem 'faraday-rack', '~> 2.0'
|
|
18
18
|
gem 'graphql', '~> 1.9'
|
|
19
19
|
gem 'graphql-errors'
|
|
20
20
|
gem 'rack-parser'
|
data/Gemfile.danger
ADDED
data/README.md
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
# Graphlient
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/rb/graphlient)
|
|
4
|
-
[](https://github.com/ashkan18/graphlient/actions/workflows/ci.yml)
|
|
5
5
|
|
|
6
6
|
A friendlier Ruby client for consuming GraphQL-based APIs. Built on top of your usual [graphql-client](https://github.com/github/graphql-client), but with better defaults, more consistent error handling, and using the [faraday](https://github.com/lostisland/faraday) HTTP client.
|
|
7
7
|
|
|
8
|
+
# Table of Contents
|
|
9
|
+
|
|
10
|
+
- [Installation](#installation)
|
|
11
|
+
- [Usage](#usage)
|
|
12
|
+
- [Schema storing and loading on disk](#schema-storing-and-loading-on-disk)
|
|
13
|
+
- [Error Handling](#error-handling)
|
|
14
|
+
- [Executing Parameterized Queries and Mutations](#executing-parameterized-queries-and-mutations)
|
|
15
|
+
- [Parse and Execute Queries Separately](#parse-and-execute-queries-separately)
|
|
16
|
+
- [Dynamic vs. Static Queries](#dynamic-vs-static-queries)
|
|
17
|
+
- [Generate Queries with Graphlient::Query](#generate-queries-with-graphlientquery)
|
|
18
|
+
- [Create API Client Classes with Graphlient::Extension::Query](#create-api-client-classes-with-graphlientextensionquery)
|
|
19
|
+
- [Swapping the HTTP Stack](#swapping-the-http-stack)
|
|
20
|
+
- [Testing with Graphlient and RSpec](#testing-with-graphlient-and-rspec)
|
|
21
|
+
- [License](#license)
|
|
22
|
+
|
|
8
23
|
## Installation
|
|
9
24
|
|
|
10
25
|
Add the following line to your Gemfile.
|
|
@@ -300,6 +315,62 @@ query.to_s
|
|
|
300
315
|
# "\nquery {\n invoice(id: 10){\n line_items\n }\n }\n"
|
|
301
316
|
```
|
|
302
317
|
|
|
318
|
+
### Use of Fragments
|
|
319
|
+
|
|
320
|
+
[Fragments](https://github.com/github/graphql-client#defining-queries) should be referred by constant:
|
|
321
|
+
|
|
322
|
+
```ruby
|
|
323
|
+
module Fragments
|
|
324
|
+
Invoice = client.parse <<~'GRAPHQL'
|
|
325
|
+
fragment on Invoice {
|
|
326
|
+
id
|
|
327
|
+
feeInCents
|
|
328
|
+
}
|
|
329
|
+
GRAPHQL
|
|
330
|
+
end
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
`Graphlient` offers the syntax below to refer to the original constant:
|
|
334
|
+
* Triple underscore `___` to refer to the fragment
|
|
335
|
+
* Double underscore `__` for namespace separator
|
|
336
|
+
|
|
337
|
+
In this example, `Fragments::Invoice` would be referred as follows:
|
|
338
|
+
|
|
339
|
+
```ruby
|
|
340
|
+
invoice_query = client.parse do
|
|
341
|
+
query do
|
|
342
|
+
invoice(id: 10) do
|
|
343
|
+
id
|
|
344
|
+
___Graphlient__InvoiceFragment
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
The wrapped response only allows access to fields that have been explicitly asked for.
|
|
351
|
+
In this example, while `id` has been referenced directly in the main query, `feeInCents` has been spread via fragment and trying to access it in the original wrapped response will throw [`GraphQL::Client::ImplicitlyFetchedFieldError`](https://github.com/github/graphql-client/blob/master/guides/implicitly-fetched-field-error.md) (to prevent data leaks between components).
|
|
352
|
+
|
|
353
|
+
```ruby
|
|
354
|
+
response = client.execute(invoice_query)
|
|
355
|
+
result = response.data.invoice
|
|
356
|
+
result.to_h
|
|
357
|
+
# {"id" => 10, "feeInCents"=> 20000}
|
|
358
|
+
result.id
|
|
359
|
+
# 10
|
|
360
|
+
result.fee_in_cents
|
|
361
|
+
# raises GraphQL::Client::ImplicitlyFetchedFieldError
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
`feeInCents` cannot be fetched directly from the main query, but from the fragment as shown below:
|
|
365
|
+
|
|
366
|
+
```ruby
|
|
367
|
+
invoice = Fragments::Invoice.new(result)
|
|
368
|
+
invoice.id
|
|
369
|
+
# 10
|
|
370
|
+
invoice.fee_in_cents
|
|
371
|
+
# 20000
|
|
372
|
+
```
|
|
373
|
+
|
|
303
374
|
### Create API Client Classes with Graphlient::Extension::Query
|
|
304
375
|
|
|
305
376
|
You can include `Graphlient::Extensions::Query` in your class. This will add a new `method_missing` method to your context which will be used to generate GraphQL queries.
|
|
@@ -435,4 +506,3 @@ end
|
|
|
435
506
|
## License
|
|
436
507
|
|
|
437
508
|
MIT License, see [LICENSE](LICENSE)
|
|
438
|
-
|
data/graphlient.gemspec
CHANGED
|
@@ -14,7 +14,6 @@ Gem::Specification.new do |s|
|
|
|
14
14
|
s.homepage = 'http://github.com/ashkan18/graphlient'
|
|
15
15
|
s.licenses = ['MIT']
|
|
16
16
|
s.summary = 'A friendlier Ruby client for consuming GraphQL-based APIs.'
|
|
17
|
-
s.add_dependency 'faraday', '
|
|
18
|
-
s.add_dependency 'faraday_middleware'
|
|
17
|
+
s.add_dependency 'faraday', '~> 2.0'
|
|
19
18
|
s.add_dependency 'graphql-client'
|
|
20
19
|
end
|
data/lib/graphlient/client.rb
CHANGED
data/lib/graphlient/query.rb
CHANGED
|
@@ -9,13 +9,15 @@ module Graphlient
|
|
|
9
9
|
|
|
10
10
|
ROOT_NODES = %w[query mutation subscription].freeze
|
|
11
11
|
|
|
12
|
+
FRAGMENT_DEFITION = /___(?<const>[A-Z][a-zA-Z0-9_]*(__[A-Z][a-zA-Z0-9_]*)*)/
|
|
13
|
+
|
|
12
14
|
attr_accessor :query_str
|
|
13
15
|
|
|
14
16
|
def initialize(&block)
|
|
15
17
|
@indents = 0
|
|
16
18
|
@query_str = ''
|
|
17
19
|
@variables = []
|
|
18
|
-
|
|
20
|
+
evaluate(&block)
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
def method_missing(method_name, *args, &block)
|
|
@@ -39,7 +41,24 @@ module Graphlient
|
|
|
39
41
|
|
|
40
42
|
private
|
|
41
43
|
|
|
44
|
+
def evaluate(&block)
|
|
45
|
+
@last_block = block || self
|
|
46
|
+
(@context ||= {})[@last_block] ||= @last_block.binding
|
|
47
|
+
instance_eval(&block)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def resolve_fragment_constant(value)
|
|
51
|
+
return nil unless (match = value.to_s.match(FRAGMENT_DEFITION))
|
|
52
|
+
raw_const = match[:const].gsub('__', '::')
|
|
53
|
+
@context[@last_block].eval(raw_const).tap do |const|
|
|
54
|
+
msg = "Expected constant #{raw_const} to be GraphQL::Client::FragmentDefinition. Given #{const.class}"
|
|
55
|
+
raise Graphlient::Errors::Error, msg unless const.is_a? GraphQL::Client::FragmentDefinition
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
42
59
|
def append_node(node, args, arg_processor: nil, &block)
|
|
60
|
+
node = "...#{resolve_fragment_constant(node)}".to_sym if node.to_s.start_with?('___')
|
|
61
|
+
|
|
43
62
|
# add field
|
|
44
63
|
@query_str << "\n#{indent}#{node}"
|
|
45
64
|
# add filter
|
|
@@ -49,7 +68,7 @@ module Graphlient
|
|
|
49
68
|
if block_given?
|
|
50
69
|
@indents += 1
|
|
51
70
|
@query_str << '{'
|
|
52
|
-
|
|
71
|
+
evaluate(&block)
|
|
53
72
|
@query_str << '}'
|
|
54
73
|
@indents -= 1
|
|
55
74
|
end
|
data/lib/graphlient/version.rb
CHANGED
|
@@ -19,8 +19,8 @@ describe Graphlient::Adapters::HTTP::FaradayAdapter do
|
|
|
19
19
|
expect(client.http.connection.builder.handlers).to eq(
|
|
20
20
|
[
|
|
21
21
|
Faraday::Response::RaiseError,
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
Faraday::Request::Json,
|
|
23
|
+
Faraday::Response::Json
|
|
24
24
|
]
|
|
25
25
|
)
|
|
26
26
|
end
|
|
@@ -65,7 +65,8 @@ describe Graphlient::Adapters::HTTP::FaradayAdapter do
|
|
|
65
65
|
before do
|
|
66
66
|
stub_request(:post, url).to_return(
|
|
67
67
|
status: 200,
|
|
68
|
-
body: DummySchema.execute(GraphQL::Introspection::INTROSPECTION_QUERY).to_json
|
|
68
|
+
body: DummySchema.execute(GraphQL::Introspection::INTROSPECTION_QUERY).to_json,
|
|
69
|
+
headers: { 'Content-Type' => 'application/json' }
|
|
69
70
|
)
|
|
70
71
|
end
|
|
71
72
|
|
|
@@ -90,7 +91,6 @@ describe Graphlient::Adapters::HTTP::FaradayAdapter do
|
|
|
90
91
|
|
|
91
92
|
specify do
|
|
92
93
|
expected_error_message = "Connection refused - #{error_message}"
|
|
93
|
-
|
|
94
94
|
expect { client.schema }.to raise_error(Graphlient::Errors::ConnectionFailedError, expected_error_message)
|
|
95
95
|
end
|
|
96
96
|
end
|
|
@@ -25,6 +25,43 @@ describe Graphlient::Client do
|
|
|
25
25
|
invoice = response.data.invoice
|
|
26
26
|
expect(invoice.id).to eq '10'
|
|
27
27
|
end
|
|
28
|
+
|
|
29
|
+
context 'with fragment' do
|
|
30
|
+
let(:invoice_fragment) do
|
|
31
|
+
client.parse <<~'GRAPHQL'
|
|
32
|
+
fragment on Invoice {
|
|
33
|
+
id
|
|
34
|
+
feeInCents
|
|
35
|
+
}
|
|
36
|
+
GRAPHQL
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
let(:invoice_fragment_const) do
|
|
40
|
+
stub_const('Graphlient::InvoiceFragment', invoice_fragment)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
let(:query) do
|
|
44
|
+
invoice_fragment_const
|
|
45
|
+
client.parse do
|
|
46
|
+
query do
|
|
47
|
+
invoice(id: 10) do
|
|
48
|
+
___Graphlient__InvoiceFragment
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it '#parse' do
|
|
55
|
+
expect(query).to be_a GraphQL::Client::OperationDefinition
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it '#execute' do
|
|
59
|
+
response = client.execute(query)
|
|
60
|
+
invoice = response.data.invoice
|
|
61
|
+
fragment = invoice_fragment.new(invoice)
|
|
62
|
+
expect(fragment.id).to eq '10'
|
|
63
|
+
end
|
|
64
|
+
end
|
|
28
65
|
end
|
|
29
66
|
|
|
30
67
|
context 'parameterized query' do
|
|
@@ -80,6 +117,29 @@ describe Graphlient::Client do
|
|
|
80
117
|
GRAPHQL
|
|
81
118
|
end
|
|
82
119
|
|
|
120
|
+
let(:execution_error_query) do
|
|
121
|
+
<<-GRAPHQL
|
|
122
|
+
query($id: Int) {
|
|
123
|
+
executionErrorInvoice(id: $id) {
|
|
124
|
+
id
|
|
125
|
+
feeInCents
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
GRAPHQL
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
let(:partial_success_query) do
|
|
132
|
+
<<-GRAPHQL
|
|
133
|
+
query {
|
|
134
|
+
someInvoices {
|
|
135
|
+
id
|
|
136
|
+
feeInCents
|
|
137
|
+
createdAt
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
GRAPHQL
|
|
141
|
+
end
|
|
142
|
+
|
|
83
143
|
it '#execute' do
|
|
84
144
|
response = client.execute(query, id: 42)
|
|
85
145
|
invoice = response.data.invoice
|
|
@@ -97,10 +157,9 @@ describe Graphlient::Client do
|
|
|
97
157
|
|
|
98
158
|
it 'fails on an execution error' do
|
|
99
159
|
expect do
|
|
100
|
-
|
|
101
|
-
client.execute(query, id: 42)
|
|
160
|
+
client.execute(execution_error_query, id: 42)
|
|
102
161
|
end.to raise_error Graphlient::Errors::ExecutionError do |e|
|
|
103
|
-
expect(e.to_s).to eq '
|
|
162
|
+
expect(e.to_s).to eq 'executionErrorInvoice: Execution Error'
|
|
104
163
|
end
|
|
105
164
|
end
|
|
106
165
|
|
|
@@ -119,6 +178,14 @@ describe Graphlient::Client do
|
|
|
119
178
|
expect(e.response).to be_a GraphQL::Client::Response
|
|
120
179
|
end
|
|
121
180
|
end
|
|
181
|
+
|
|
182
|
+
it 'fails with a partial error response' do
|
|
183
|
+
expect do
|
|
184
|
+
client.execute(partial_success_query)
|
|
185
|
+
end.to raise_error Graphlient::Errors::ExecutionError do |e|
|
|
186
|
+
expect(e.response).to be_a GraphQL::Client::Response
|
|
187
|
+
end
|
|
188
|
+
end
|
|
122
189
|
end
|
|
123
190
|
|
|
124
191
|
context 'non-parameterized query' do
|
|
@@ -7,13 +7,23 @@ describe Graphlient::Client do
|
|
|
7
7
|
|
|
8
8
|
describe '#schema' do
|
|
9
9
|
before do
|
|
10
|
-
stub_request(:post, url)
|
|
11
|
-
|
|
10
|
+
stub_request(:post, url).to_return(
|
|
11
|
+
body: DummySchema.execute(GraphQL::Introspection::INTROSPECTION_QUERY).to_json,
|
|
12
|
+
headers: { 'Content-Type' => 'application/json' }
|
|
13
|
+
)
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
context 'when server returns error' do
|
|
15
17
|
before do
|
|
16
|
-
stub_request(:post, url).to_return(
|
|
18
|
+
stub_request(:post, url).to_return(
|
|
19
|
+
status: 500,
|
|
20
|
+
body: {
|
|
21
|
+
errors: [
|
|
22
|
+
{ message: 'test message', extensions: { code: 'SOMETHING', timestamp: Time.now } }
|
|
23
|
+
]
|
|
24
|
+
}.to_json,
|
|
25
|
+
headers: { 'Content-Type' => 'application/json' }
|
|
26
|
+
)
|
|
17
27
|
end
|
|
18
28
|
|
|
19
29
|
it 'fails with an exception' do
|
|
@@ -10,7 +10,10 @@ describe Graphlient::Schema do
|
|
|
10
10
|
let!(:introspection_query_request) do
|
|
11
11
|
stub_request(:post, url)
|
|
12
12
|
.with(body: /query IntrospectionQuery/)
|
|
13
|
-
.to_return(
|
|
13
|
+
.to_return(
|
|
14
|
+
body: DummySchema.execute(GraphQL::Introspection::INTROSPECTION_QUERY).to_json,
|
|
15
|
+
headers: { 'Content-Type' => 'application/json' }
|
|
16
|
+
)
|
|
14
17
|
end
|
|
15
18
|
|
|
16
19
|
context 'when schema path is not given' do
|
data/spec/spec_helper.rb
CHANGED
|
@@ -10,6 +10,15 @@ class Query < GraphQL::Schema::Object
|
|
|
10
10
|
argument :id, Integer, required: false
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
+
field :execution_error_invoice, InvoiceType, null: false, extras: [:execution_errors] do
|
|
14
|
+
description 'Find invoice'
|
|
15
|
+
argument :id, Integer, required: false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
field :some_invoices, [InvoiceType], null: true do
|
|
19
|
+
description 'List of invoices'
|
|
20
|
+
end
|
|
21
|
+
|
|
13
22
|
def invoice(id: nil)
|
|
14
23
|
return nil if id.nil?
|
|
15
24
|
OpenStruct.new(
|
|
@@ -21,4 +30,18 @@ class Query < GraphQL::Schema::Object
|
|
|
21
30
|
def not_null_invoice(*)
|
|
22
31
|
nil
|
|
23
32
|
end
|
|
33
|
+
|
|
34
|
+
def execution_error_invoice(id: nil, execution_errors:)
|
|
35
|
+
execution_errors.add(GraphQL::ExecutionError.new('Execution Error'))
|
|
36
|
+
|
|
37
|
+
invoice(id: id)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def some_invoices
|
|
41
|
+
[
|
|
42
|
+
OpenStruct.new(id: 0, fee_in_cents: 20_000),
|
|
43
|
+
OpenStruct.new(id: 1, fee_in_cents: 20_000),
|
|
44
|
+
OpenStruct.new(id: 2, fee_in_cents: 20_000)
|
|
45
|
+
]
|
|
46
|
+
end
|
|
24
47
|
end
|
|
@@ -4,4 +4,10 @@ class InvoiceType < GraphQL::Schema::Object
|
|
|
4
4
|
|
|
5
5
|
field :id, ID, null: false
|
|
6
6
|
field :fee_in_cents, Integer, null: true
|
|
7
|
+
field :created_at, String, null: true, extras: [:execution_errors]
|
|
8
|
+
|
|
9
|
+
def created_at(execution_errors:)
|
|
10
|
+
execution_errors.add(GraphQL::ExecutionError.new('This is a partial error'))
|
|
11
|
+
Time.now.iso8601
|
|
12
|
+
end
|
|
7
13
|
end
|
metadata
CHANGED
|
@@ -1,43 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: graphlient
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ashkan Nasseri
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-10-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '2.0'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- - "
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '1.0'
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: faraday_middleware
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - ">="
|
|
24
|
+
- - "~>"
|
|
32
25
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
34
|
-
type: :runtime
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - ">="
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
26
|
+
version: '2.0'
|
|
41
27
|
- !ruby/object:Gem::Dependency
|
|
42
28
|
name: graphql-client
|
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -58,15 +44,20 @@ executables: []
|
|
|
58
44
|
extensions: []
|
|
59
45
|
extra_rdoc_files: []
|
|
60
46
|
files:
|
|
47
|
+
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
|
48
|
+
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
|
49
|
+
- ".github/workflows/ci.yml"
|
|
50
|
+
- ".github/workflows/danger.yml"
|
|
51
|
+
- ".github/workflows/rubocop.yml"
|
|
61
52
|
- ".gitignore"
|
|
62
53
|
- ".rspec"
|
|
63
54
|
- ".rubocop.yml"
|
|
64
55
|
- ".rubocop_todo.yml"
|
|
65
|
-
- ".travis.yml"
|
|
66
56
|
- CHANGELOG.md
|
|
67
57
|
- CONTRIBUTING.md
|
|
68
58
|
- Dangerfile
|
|
69
59
|
- Gemfile
|
|
60
|
+
- Gemfile.danger
|
|
70
61
|
- LICENSE
|
|
71
62
|
- README.md
|
|
72
63
|
- RELEASING.md
|
|
@@ -140,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
140
131
|
- !ruby/object:Gem::Version
|
|
141
132
|
version: 1.3.6
|
|
142
133
|
requirements: []
|
|
143
|
-
rubygems_version: 3.
|
|
134
|
+
rubygems_version: 3.1.4
|
|
144
135
|
signing_key:
|
|
145
136
|
specification_version: 4
|
|
146
137
|
summary: A friendlier Ruby client for consuming GraphQL-based APIs.
|
data/.travis.yml
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
language: ruby
|
|
2
|
-
|
|
3
|
-
cache: bundler
|
|
4
|
-
|
|
5
|
-
rvm:
|
|
6
|
-
- 2.5.0
|
|
7
|
-
- 2.7.2
|
|
8
|
-
- 3.0.0
|
|
9
|
-
- ruby-head
|
|
10
|
-
- jruby-9.1.16.0
|
|
11
|
-
- jruby-head
|
|
12
|
-
|
|
13
|
-
before_install:
|
|
14
|
-
- gem update --system
|
|
15
|
-
|
|
16
|
-
matrix:
|
|
17
|
-
include:
|
|
18
|
-
- rvm: 2.7.2
|
|
19
|
-
script:
|
|
20
|
-
- bundle exec danger
|
|
21
|
-
allow_failures:
|
|
22
|
-
- rvm: ruby-head
|
|
23
|
-
- rvm: jruby-9.1.16.0
|
|
24
|
-
- rvm: jruby-head
|