gqli 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +31 -0
  5. data/.rubocop_todo.yml +44 -0
  6. data/.travis.yml +13 -0
  7. data/.yardopts +4 -0
  8. data/CHANGELOG.md +9 -0
  9. data/Gemfile +9 -0
  10. data/Gemfile.lock +154 -0
  11. data/Guardfile +24 -0
  12. data/LICENSE.txt +21 -0
  13. data/README.md +284 -0
  14. data/Rakefile +33 -0
  15. data/coverage/.last_run.json +5 -0
  16. data/coverage/.resultset.json +512 -0
  17. data/coverage/.resultset.json.lock +0 -0
  18. data/coverage/assets/0.10.2/application.css +799 -0
  19. data/coverage/assets/0.10.2/application.js +1707 -0
  20. data/coverage/assets/0.10.2/colorbox/border.png +0 -0
  21. data/coverage/assets/0.10.2/colorbox/controls.png +0 -0
  22. data/coverage/assets/0.10.2/colorbox/loading.gif +0 -0
  23. data/coverage/assets/0.10.2/colorbox/loading_background.png +0 -0
  24. data/coverage/assets/0.10.2/favicon_green.png +0 -0
  25. data/coverage/assets/0.10.2/favicon_red.png +0 -0
  26. data/coverage/assets/0.10.2/favicon_yellow.png +0 -0
  27. data/coverage/assets/0.10.2/loading.gif +0 -0
  28. data/coverage/assets/0.10.2/magnify.png +0 -0
  29. data/coverage/assets/0.10.2/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  30. data/coverage/assets/0.10.2/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  31. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  32. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  33. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  34. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  35. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  36. data/coverage/assets/0.10.2/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  37. data/coverage/assets/0.10.2/smoothness/images/ui-icons_222222_256x240.png +0 -0
  38. data/coverage/assets/0.10.2/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  39. data/coverage/assets/0.10.2/smoothness/images/ui-icons_454545_256x240.png +0 -0
  40. data/coverage/assets/0.10.2/smoothness/images/ui-icons_888888_256x240.png +0 -0
  41. data/coverage/assets/0.10.2/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  42. data/coverage/index.html +3255 -0
  43. data/doc/GQLi/Base.html +628 -0
  44. data/doc/GQLi/Client.html +830 -0
  45. data/doc/GQLi/DSL.html +421 -0
  46. data/doc/GQLi/Fragment.html +405 -0
  47. data/doc/GQLi/Introspection.html +837 -0
  48. data/doc/GQLi/Node.html +413 -0
  49. data/doc/GQLi/Query.html +390 -0
  50. data/doc/GQLi/Response.html +370 -0
  51. data/doc/GQLi.html +157 -0
  52. data/doc/_index.html +236 -0
  53. data/doc/class_list.html +51 -0
  54. data/doc/css/common.css +1 -0
  55. data/doc/css/full_list.css +58 -0
  56. data/doc/css/style.css +496 -0
  57. data/doc/file.CHANGELOG.html +76 -0
  58. data/doc/file.LICENSE.html +70 -0
  59. data/doc/file.README.html +365 -0
  60. data/doc/file_list.html +66 -0
  61. data/doc/frames.html +17 -0
  62. data/doc/index.html +365 -0
  63. data/doc/js/app.js +292 -0
  64. data/doc/js/full_list.js +216 -0
  65. data/doc/js/jquery.js +4 -0
  66. data/doc/method_list.html +355 -0
  67. data/doc/top-level-namespace.html +110 -0
  68. data/gqli.gemspec +37 -0
  69. data/lib/gqli/base.rb +53 -0
  70. data/lib/gqli/client.rb +59 -0
  71. data/lib/gqli/dsl.rb +37 -0
  72. data/lib/gqli/fragment.rb +25 -0
  73. data/lib/gqli/introspection.rb +215 -0
  74. data/lib/gqli/node.rb +48 -0
  75. data/lib/gqli/query.rb +29 -0
  76. data/lib/gqli/response.rb +15 -0
  77. data/lib/gqli/version.rb +7 -0
  78. data/lib/gqli.rb +6 -0
  79. data/spec/fixtures/vcr_cassettes/catCollection.yml +63 -0
  80. data/spec/fixtures/vcr_cassettes/client.yml +171 -0
  81. data/spec/fixtures/vcr_cassettes/validation_error.yml +62 -0
  82. data/spec/lib/gqli/client_spec.rb +90 -0
  83. data/spec/lib/gqli/dsl_spec.rb +205 -0
  84. data/spec/lib/gqli/introspection_spec.rb +125 -0
  85. data/spec/spec_helper.rb +25 -0
  86. data/usage.rb +100 -0
  87. data/usage_introspection.rb +63 -0
  88. data/usage_with_inlined_dsl.rb +69 -0
  89. metadata +387 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5a92aeb50f3395eeb402d70097e5a90b95f78c8ccf9971c92635f4423748a52b
4
+ data.tar.gz: 49d4f4186b14b60b38383e0436940049e6c489857854652daff112ec9e5f94d8
5
+ SHA512:
6
+ metadata.gz: f1b611ab9b505ed267a4c0ecb943d357fc250f4221a07351b3b8ea5dd9968cba1d03aea84b64d9c727719cb1acc3f74aec12dda3f14b6f8ab82fd5aba786b23d
7
+ data.tar.gz: f314024396af8dab242f65136da3cd42248976824454ca105d84390902f8b974c6c0c776c4e76b2f7bc60853dcb8d88e09ad0787690d0fc087cfd6113f896050
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ pkg
2
+ doc/
3
+ .yardoc/
4
+ coverage
5
+ Gemfile.lock
6
+ .idea
7
+ *.DS_Store
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format documentation
3
+ --order random
data/.rubocop.yml ADDED
@@ -0,0 +1,31 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ Encoding:
4
+ Enabled: false
5
+
6
+ Metrics/ClassLength:
7
+ CountComments: false
8
+
9
+ Metrics/MethodLength:
10
+ CountComments: false
11
+
12
+ AllCops:
13
+ TargetRubyVersion: 2.3
14
+
15
+ Exclude:
16
+ - gqli.gemspec
17
+ - spec/**/*
18
+ - examples/**/*
19
+ - Guardfile
20
+ - Gemfile
21
+ - Rakefile
22
+ - usage*.rb
23
+
24
+ Metrics/ClassLength:
25
+ Max: 250
26
+
27
+ Style/MutableConstant:
28
+ Enabled: false
29
+
30
+ Style/SignalException:
31
+ EnforcedStyle: 'semantic'
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,44 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2018-10-05 15:34:48 +0200 using RuboCop version 0.49.1.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 3
10
+ Metrics/AbcSize:
11
+ Max: 20
12
+
13
+ # Blocks can be arbitrarily long due to GraphQL DSL syntax.
14
+ Metrics/BlockLength:
15
+ Max: 30
16
+
17
+ # Offense count: 1
18
+ Metrics/CyclomaticComplexity:
19
+ Max: 11
20
+
21
+ # Offense count: 8
22
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
23
+ # URISchemes: http, https
24
+ Metrics/LineLength:
25
+ Max: 114
26
+
27
+ # Offense count: 3
28
+ # Configuration parameters: CountComments.
29
+ Metrics/MethodLength:
30
+ Max: 15
31
+
32
+ # Offense count: 1
33
+ Metrics/PerceivedComplexity:
34
+ Max: 8
35
+
36
+ # Block delimiters are `{...}` to match GraphQL syntax more closely.
37
+ Style/BlockDelimiters:
38
+ Exclude:
39
+ - 'lib/gqli/introspection.rb'
40
+
41
+ # We on purpose don't want method missing working as it is supposed in the context of the DSL
42
+ Style/MethodMissing:
43
+ Exclude:
44
+ - 'lib/gqli/base.rb'
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.4.0
4
+ - 2.3.1
5
+ - 2.2.1
6
+ notifications:
7
+ slack:
8
+ secure: Zr3mKCiTb0vaTD4MPtTG8BbyYyErFuoxioM25QyrqePKVkDFeZC1MtGmg5klQQrJiWTKZPa/zB8NAHYkoUxg9I+z15JK0hYfz9KRubEpCrXCaqTC9Vzq88kJ3LN8YsTyBF66izaBH2KLsOfaJRxwplFzZqgpg4GG2DUBPtrGtes=
9
+ before_install: gem install bundler -v 1.10.6
10
+ script: bundle exec rake rspec_rubocop
11
+ matrix:
12
+ allow_failures:
13
+ - rvm: jruby
data/.yardopts ADDED
@@ -0,0 +1,4 @@
1
+ --no-private
2
+ -
3
+ CHANGELOG.md
4
+ LICENSE.txt
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # CHANGELOG
2
+
3
+ ## v0.1.0
4
+
5
+ Initial Release
6
+
7
+ Included features:
8
+ * Create queries and fragments using the `GQLi::DSL`.
9
+ * HTTP client with automatic schema introspection and validation.
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'listen', '3.0.6'
6
+
7
+ group :documentation do
8
+ gem 'coveralls', :require => false
9
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,154 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ gqli (0.1.0)
5
+ hashie (~> 3.0)
6
+ http (> 0.8, < 3.0)
7
+ multi_json (~> 1)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ addressable (2.5.2)
13
+ public_suffix (>= 2.0.2, < 4.0)
14
+ ast (2.4.0)
15
+ coderay (1.1.2)
16
+ coveralls (0.8.22)
17
+ json (>= 1.8, < 3)
18
+ simplecov (~> 0.16.1)
19
+ term-ansicolor (~> 1.3)
20
+ thor (~> 0.19.4)
21
+ tins (~> 1.6)
22
+ crack (0.4.3)
23
+ safe_yaml (~> 1.0.0)
24
+ diff-lcs (1.3)
25
+ docile (1.3.1)
26
+ domain_name (0.5.20180417)
27
+ unf (>= 0.0.5, < 1.0.0)
28
+ ffi (1.9.25)
29
+ formatador (0.2.5)
30
+ guard (2.14.2)
31
+ formatador (>= 0.2.4)
32
+ listen (>= 2.7, < 4.0)
33
+ lumberjack (>= 1.0.12, < 2.0)
34
+ nenv (~> 0.1)
35
+ notiffany (~> 0.0)
36
+ pry (>= 0.9.12)
37
+ shellany (~> 0.0)
38
+ thor (>= 0.18.1)
39
+ guard-compat (1.2.1)
40
+ guard-rspec (4.7.3)
41
+ guard (~> 2.1)
42
+ guard-compat (~> 1.1)
43
+ rspec (>= 2.99.0, < 4.0)
44
+ guard-rubocop (1.3.0)
45
+ guard (~> 2.0)
46
+ rubocop (~> 0.20)
47
+ guard-yard (2.2.1)
48
+ guard (>= 1.1.0)
49
+ yard (>= 0.7.0)
50
+ hashdiff (0.3.7)
51
+ hashie (3.6.0)
52
+ http (2.2.2)
53
+ addressable (~> 2.3)
54
+ http-cookie (~> 1.0)
55
+ http-form_data (~> 1.0.1)
56
+ http_parser.rb (~> 0.6.0)
57
+ http-cookie (1.0.3)
58
+ domain_name (~> 0.5)
59
+ http-form_data (1.0.3)
60
+ http_parser.rb (0.6.0)
61
+ json (2.1.0)
62
+ listen (3.0.6)
63
+ rb-fsevent (>= 0.9.3)
64
+ rb-inotify (>= 0.9.7)
65
+ lumberjack (1.0.13)
66
+ method_source (0.9.0)
67
+ multi_json (1.13.1)
68
+ nenv (0.3.0)
69
+ notiffany (0.1.1)
70
+ nenv (~> 0.1)
71
+ shellany (~> 0.0)
72
+ parallel (1.12.1)
73
+ parser (2.5.1.2)
74
+ ast (~> 2.4.0)
75
+ powerpack (0.1.2)
76
+ pry (0.11.3)
77
+ coderay (~> 1.1.0)
78
+ method_source (~> 0.9.0)
79
+ public_suffix (3.0.3)
80
+ rainbow (2.2.2)
81
+ rake
82
+ rake (10.5.0)
83
+ rb-fsevent (0.10.3)
84
+ rb-inotify (0.9.10)
85
+ ffi (>= 0.5.0, < 2)
86
+ rr (1.2.1)
87
+ rspec (3.8.0)
88
+ rspec-core (~> 3.8.0)
89
+ rspec-expectations (~> 3.8.0)
90
+ rspec-mocks (~> 3.8.0)
91
+ rspec-core (3.8.0)
92
+ rspec-support (~> 3.8.0)
93
+ rspec-expectations (3.8.1)
94
+ diff-lcs (>= 1.2.0, < 2.0)
95
+ rspec-support (~> 3.8.0)
96
+ rspec-mocks (3.8.0)
97
+ diff-lcs (>= 1.2.0, < 2.0)
98
+ rspec-support (~> 3.8.0)
99
+ rspec-support (3.8.0)
100
+ rubocop (0.49.1)
101
+ parallel (~> 1.10)
102
+ parser (>= 2.3.3.1, < 3.0)
103
+ powerpack (~> 0.1)
104
+ rainbow (>= 1.99.1, < 3.0)
105
+ ruby-progressbar (~> 1.7)
106
+ unicode-display_width (~> 1.0, >= 1.0.1)
107
+ ruby-progressbar (1.10.0)
108
+ rubygems-tasks (0.2.4)
109
+ safe_yaml (1.0.4)
110
+ shellany (0.0.1)
111
+ simplecov (0.16.1)
112
+ docile (~> 1.1)
113
+ json (>= 1.8, < 3)
114
+ simplecov-html (~> 0.10.0)
115
+ simplecov-html (0.10.2)
116
+ term-ansicolor (1.6.0)
117
+ tins (~> 1.0)
118
+ thor (0.19.4)
119
+ tins (1.6.0)
120
+ unf (0.1.4)
121
+ unf_ext
122
+ unf_ext (0.0.7.5)
123
+ unicode-display_width (1.4.0)
124
+ vcr (4.0.0)
125
+ webmock (1.24.6)
126
+ addressable (>= 2.3.6)
127
+ crack (>= 0.3.2)
128
+ hashdiff
129
+ yard (0.9.16)
130
+
131
+ PLATFORMS
132
+ ruby
133
+
134
+ DEPENDENCIES
135
+ bundler (~> 1.5)
136
+ coveralls
137
+ gqli!
138
+ guard
139
+ guard-rspec
140
+ guard-rubocop
141
+ guard-yard
142
+ listen (= 3.0.6)
143
+ rake (< 11.0)
144
+ rr
145
+ rspec (~> 3)
146
+ rubocop (~> 0.49.1)
147
+ rubygems-tasks (~> 0.2)
148
+ simplecov
149
+ tins (~> 1.6.0)
150
+ vcr
151
+ webmock (~> 1, >= 1.17.3)
152
+
153
+ BUNDLED WITH
154
+ 1.16.3
data/Guardfile ADDED
@@ -0,0 +1,24 @@
1
+ group :green_red_refactor, halt_on_fail: true do
2
+ guard :rspec, cmd: "bundle exec rspec" do
3
+ require "guard/rspec/dsl"
4
+ dsl = Guard::RSpec::Dsl.new(self)
5
+
6
+ # Feel free to open issues for suggestions and improvements
7
+
8
+ # RSpec files
9
+ rspec = dsl.rspec
10
+ watch(rspec.spec_helper) { rspec.spec_dir }
11
+ watch(rspec.spec_support) { rspec.spec_dir }
12
+ watch(rspec.spec_files)
13
+
14
+ # Ruby files
15
+ ruby = dsl.ruby
16
+ dsl.watch_spec_files_for(ruby.lib_files)
17
+ end
18
+
19
+ guard :yard, cmd: "yard doc" do
20
+ end
21
+
22
+ guard :rubocop, cmd: "rubocop" do
23
+ end
24
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Contentful GmbH - David Litvak
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,284 @@
1
+ # GQLi - GraphQL Client for humans
2
+
3
+ GQLi is a DSL (Domain Specific Language) to consume GraphQL APIs.
4
+
5
+ > **DISCLAIMER:**
6
+ >
7
+ > This gem is in stable state and will be updated with more features.
8
+ > You can start using it for your respective projects, although there is no support available from Contentful.
9
+ >
10
+ > This gem is not covered under the Contentful SLAs.
11
+ >
12
+ > Users are free to create Github issues and collaborate.
13
+
14
+ ## Installation
15
+
16
+ Install it via the command line:
17
+
18
+ ```bash
19
+ gem install gqli
20
+ ```
21
+
22
+ Or add it to your `Gemfile`:
23
+
24
+ ```ruby
25
+ gem 'gqli'
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ ### Creating a GraphQL Client
31
+
32
+ For the examples throughout this README, we'll be using the Contentful and Github GraphQL APIs.
33
+ Therefore, here's the initialization code required for both of them:
34
+
35
+ ```ruby
36
+ require 'gqli'
37
+
38
+ # Creating a Contentful GraphQL Client
39
+ SPACE_ID = 'cfexampleapi'
40
+ CF_ACCESS_TOKEN = 'b4c0n73n7fu1'
41
+ CONTENTFUL_GQL = GQLi::Client.new(
42
+ "https://graphql.contentful.com/content/v1/spaces/#{SPACE_ID}",
43
+ headers: { "Authorization" => "Bearer #{CF_ACCESS_TOKEN}" }
44
+ )
45
+
46
+ # Creating a Github GraphQL Client
47
+ GITHUB_ACCESS_TOKEN = ENV['GITHUB_TOKEN']
48
+ GITHUB_GQL = GQLi::Client.new(
49
+ "https://api.github.com/graphql",
50
+ headers: { "Authorization" => "Bearer #{GITHUB_ACCESS_TOKEN}" }
51
+ )
52
+ ```
53
+
54
+ ### Creating a Query
55
+
56
+ Queries are the way to request data from a GraphQL API.
57
+ This gem provides a simple DSL to create your own queries.
58
+
59
+ The query operator is `GQLi::DSL.query`.
60
+
61
+ ```ruby
62
+ # Query to fetch the usernames for the first 10 watchers of the first 10 repositories I belong to
63
+ WatchersQuery = GQLi::DSL.query {
64
+ viewer {
65
+ login
66
+ repositories(first: 10) {
67
+ edges {
68
+ node {
69
+ nameWithOwner
70
+ watchers(first: 10) {
71
+ edges {
72
+ node {
73
+ login
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
81
+ }
82
+ ```
83
+
84
+ ### Divide and conquer - using Fragments
85
+
86
+ In order to reuse parts of queries, we can split chunks of our queries into Fragments.
87
+
88
+ The fragment operator is `GQLi::DSL.fragment`.
89
+
90
+ To include fragments within other nodes, use the `___` operator as shown below.
91
+
92
+ To do type matching, use the `__on` operator as shown below.
93
+
94
+ ```ruby
95
+ # Base fragment that will be reused for all Cat queries.
96
+ CatBase = GQLi::DSL.fragment('CatBase', 'Cat') {
97
+ name
98
+ likes
99
+ lives
100
+ }
101
+
102
+ CatBestFriend = GQLi::DSL.fragment('CatBestFriend', 'Cat') {
103
+ bestFriend {
104
+ # Here, because `bestFriend` is polimorphic in our GraphQL API,
105
+ # we need to explicitly state for which Type we want to include our fragment.
106
+ # To do a type match, instead of GraphQLs `... on SomeType` we do `__on('SomeType')`.
107
+ __on('Cat') {
108
+ # To include a fragment, instead of GraphQLs `...`, we use `___`.
109
+ ___ CatBase
110
+ }
111
+ }
112
+ }
113
+
114
+ # A fragment reusing multiple fragments
115
+ CatImportantFields = GQLi::DSL.fragment('CatImportantFields', 'Cat') {
116
+ ___ CatBase
117
+ ___ CatBestFriend
118
+ }
119
+
120
+ # A fragment used to define a query, alongside other regular fields.
121
+ CatQuery = GQLi::DSL.query {
122
+ catCollection(limit: 1) {
123
+ items {
124
+ ___ CatImportantFields
125
+ image {
126
+ url
127
+ }
128
+ }
129
+ }
130
+ }
131
+ ```
132
+
133
+ ### Executing the queries
134
+
135
+ To execute the queries, you need to pass a `Query` object to the client's `#execute` method.
136
+ This will return a `Response` object which contains the `data` and the `query` executed.
137
+
138
+ For example:
139
+
140
+ ```ruby
141
+ response = CONTENTFUL_GQL.execute(CatQuery)
142
+
143
+ puts "Query sent:"
144
+ puts response.query.to_gql
145
+
146
+ puts
147
+ puts "Response received"
148
+ response.data.catCollection.items.each do |c|
149
+ puts "Name: #{c.nam}e"
150
+ puts "Likes: #{c.likes.join(", ")}"
151
+ puts "Lives #: #{c.lives}"
152
+ c.bestFriend.tap do |bf|
153
+ puts "Best Friend:"
154
+ puts "\tName: #{bf.name}"
155
+ puts "\tLikes: #{bf.likes.join(", ")}"
156
+ puts "\tLives #: #{bf.lives}"
157
+ end
158
+ end
159
+ ```
160
+
161
+ The output is:
162
+
163
+ ```
164
+ Query sent:
165
+ query {
166
+ catCollection(limit: 1) {
167
+ items {
168
+ name
169
+ likes
170
+ lives
171
+ bestFriend {
172
+ ... on Cat {
173
+ name
174
+ likes
175
+ lives
176
+ }
177
+ }
178
+ image {
179
+ url
180
+ }
181
+ }
182
+ }
183
+ }
184
+
185
+ Response received
186
+ Name: e
187
+ Likes: cheezburger
188
+ Lives #: 1
189
+ Best Friend:
190
+ Name: Nyan Cat
191
+ Likes: rainbows, fish
192
+ Lives #: 1337
193
+ ```
194
+
195
+ ### Schema Introspection and Validation
196
+
197
+ By default this library will fetch and cache a copy of the GraphQL Schema for any API you create a client for.
198
+
199
+ This schema is used for query validation before running queries against the APIs. In case a query is invalid for the given schema, an exception will be raised.
200
+
201
+ To disable schema caching completely, when you initialize your client, send `validate_query: false`.
202
+
203
+ Queries executed using the `#execute` method on the client will be validated before executing the request if the option is set to `true` (which it is by default).
204
+
205
+ To avoid validating a query, you can use `#execute!` instead.
206
+
207
+ To validate the query outside of the scope of an HTTP request, you can use `MY_CLIENT.schema.valid?(query)`.
208
+
209
+ ### Embedding the DSL in your classes
210
+
211
+ If you want to avoid the need for prepending all GQLi DSL's calls with `GQLi::DSL.`, then you can `extend` and/or `include` the module within your own classes.
212
+ When using `extend`, you will have access to the DSL at a class level. When using `include` you will have access to the DSL at an object level.
213
+
214
+ ```ruby
215
+ class ContentfulClient
216
+ extend GQLi::DSL # Makes DSL available at a class level
217
+ include GQLi::DSL # Makes DSL available at an object level
218
+
219
+ SPACE_ID = 'cfexampleapi'
220
+ ACCESS_TOKEN = 'b4c0n73n7fu1'
221
+ CONTENTFUL_GQL = GQLi::Client.new(
222
+ "https://graphql.contentful.com/content/v1/spaces/#{SPACE_ID}",
223
+ headers: { "Authorization" => "Bearer #{ACCESS_TOKEN}" }
224
+ )
225
+
226
+ CatBase = fragment('CatBase', 'Cat') {
227
+ name
228
+ likes
229
+ lives
230
+ }
231
+
232
+ CatBestFriend = fragment('CatBestFriend', 'Cat') {
233
+ bestFriend {
234
+ __on('Cat') {
235
+ ___ CatBase
236
+ }
237
+ }
238
+ }
239
+
240
+ CatImportantFields = fragment('CatImportantFields', 'Cat') {
241
+ ___ CatBase
242
+ ___ CatBestFriend
243
+ }
244
+
245
+ def cats(limit)
246
+ CONTENTFUL_GQL.execute(
247
+ query {
248
+ catCollection(limit: limit) {
249
+ items {
250
+ ___ CatImportantFields
251
+ image {
252
+ url
253
+ }
254
+ }
255
+ }
256
+ }
257
+ )
258
+ end
259
+ end
260
+
261
+ response = ContentfulClient.new.cats(5)
262
+ ```
263
+
264
+ ## Yet to be implemented
265
+
266
+ * Mutation queries
267
+ * Subscription queries
268
+ * Detailed validation errors
269
+
270
+ ## Get involved
271
+
272
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?maxAge=31557600)](http://makeapullrequest.com)
273
+
274
+ We appreciate any help on our repositories.
275
+
276
+ ## License
277
+
278
+ This repository is published under the [MIT](LICENSE.txt) license.
279
+
280
+ ## Code of Conduct
281
+
282
+ We want to provide a safe, inclusive, welcoming, and harassment-free space and experience for all participants, regardless of gender identity and expression, sexual orientation, disability, physical appearance, socioeconomic status, body size, ethnicity, nationality, level of experience, age, religion (or lack thereof), or other identity markers.
283
+
284
+ [Read our full Code of Conduct](https://github.com/contentful-developer-relations/community-code-of-conduct).
data/Rakefile ADDED
@@ -0,0 +1,33 @@
1
+ require 'rubygems'
2
+
3
+ begin
4
+ require 'bundler'
5
+ rescue LoadError => e
6
+ warn e.message
7
+ warn 'Run `gem install bundler` to install Bundler.'
8
+ exit -1
9
+ end
10
+
11
+ begin
12
+ Bundler.setup(:development)
13
+ rescue Bundler::BundlerError => e
14
+ warn e.message
15
+ warn 'Run `bundle install` to install missing gems.'
16
+ exit e.status_code
17
+ end
18
+
19
+ require 'rake'
20
+
21
+ require 'rubygems/tasks'
22
+ Gem::Tasks.new
23
+
24
+ require 'rspec/core/rake_task'
25
+ RSpec::Core::RakeTask.new
26
+
27
+ require 'rubocop/rake_task'
28
+ RuboCop::RakeTask.new
29
+
30
+ task rspec_rubocop: %w(spec rubocop)
31
+
32
+ task test: :spec
33
+ task default: :spec
@@ -0,0 +1,5 @@
1
+ {
2
+ "result": {
3
+ "covered_percent": 94.02
4
+ }
5
+ }