graphiti 2.0.0.beta.7 → 2.0.0.beta.8

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.
Files changed (238) hide show
  1. checksums.yaml +4 -4
  2. data/.git-blame-ignore-revs +2 -0
  3. data/.github/workflows/ci.yml +55 -3
  4. data/.github/workflows/docs.yml +1 -1
  5. data/.github/workflows/notify-example-app.yml +18 -0
  6. data/.gitignore +2 -0
  7. data/.standard.yml +6 -0
  8. data/CHANGELOG.md +45 -0
  9. data/CONTRIBUTING.md +3 -1
  10. data/README.md +13 -206
  11. data/Rakefile +6 -3
  12. data/UPGRADING.md +1 -1
  13. data/graphiti.gemspec +8 -4
  14. data/lib/generators/graphiti/generator_mixin.rb +1 -1
  15. data/lib/generators/graphiti/install_generator.rb +1 -1
  16. data/lib/generators/graphiti/resource_generator.rb +6 -3
  17. data/lib/generators/graphiti/templates/application_resource.rb.erb +19 -0
  18. data/lib/generators/graphiti/templates/controller.rb.erb +26 -8
  19. data/lib/graphiti/audit/report.rb +6 -6
  20. data/lib/graphiti/audit.rb +3 -4
  21. data/lib/graphiti/delegates/pagination.rb +2 -2
  22. data/lib/graphiti/deserializer.rb +3 -3
  23. data/lib/graphiti/errors.rb +6 -6
  24. data/lib/graphiti/extensions/temp_id.rb +1 -1
  25. data/lib/graphiti/query.rb +3 -3
  26. data/lib/graphiti/rails/context.rb +2 -1
  27. data/lib/graphiti/rails/controller.rb +3 -0
  28. data/lib/graphiti/rails/debugging.rb +1 -1
  29. data/lib/graphiti/rails/responders.rb +2 -1
  30. data/lib/graphiti/resource/configuration.rb +1 -0
  31. data/lib/graphiti/resource/dsl.rb +2 -2
  32. data/lib/graphiti/resource/links.rb +1 -1
  33. data/lib/graphiti/resource/persistence.rb +1 -1
  34. data/lib/graphiti/resource/polymorphism.rb +1 -1
  35. data/lib/graphiti/resource.rb +2 -2
  36. data/lib/graphiti/resource_proxy.rb +0 -1
  37. data/lib/graphiti/scoping/filter.rb +5 -3
  38. data/lib/graphiti/scoping/paginate.rb +1 -1
  39. data/lib/graphiti/scoping/sort.rb +1 -1
  40. data/lib/graphiti/sideload/has_many.rb +1 -1
  41. data/lib/graphiti/spec_helpers/errors_proxy.rb +1 -1
  42. data/lib/graphiti/spec_helpers/matchers.rb +1 -1
  43. data/lib/graphiti/types.rb +5 -1
  44. data/lib/graphiti/util/cache_debug.rb +3 -3
  45. data/lib/graphiti/util/hash.rb +1 -1
  46. data/lib/graphiti/util/persistence.rb +6 -6
  47. data/lib/graphiti/util/serializer_relationships.rb +1 -1
  48. data/lib/graphiti/version.rb +1 -1
  49. data/lib/tasks/graphiti.rake +1 -1
  50. metadata +31 -197
  51. data/docs/concepts/backends-and-models.md +0 -122
  52. data/docs/concepts/endpoints.md +0 -183
  53. data/docs/concepts/links.md +0 -212
  54. data/docs/concepts/overview.md +0 -80
  55. data/docs/concepts/persisting.md +0 -376
  56. data/docs/concepts/relationships.md +0 -627
  57. data/docs/concepts/resources.md +0 -677
  58. data/docs/getting-started/first-api.md +0 -289
  59. data/docs/getting-started/installation.md +0 -185
  60. data/docs/intro.md +0 -307
  61. data/docs/js/authentication.md +0 -63
  62. data/docs/js/ddau.md +0 -20
  63. data/docs/js/extra-params.md +0 -41
  64. data/docs/js/index.md +0 -112
  65. data/docs/js/installation.md +0 -120
  66. data/docs/js/middleware.md +0 -72
  67. data/docs/js/models.md +0 -202
  68. data/docs/js/reads.md +0 -494
  69. data/docs/js/state-syncing.md +0 -100
  70. data/docs/js/writes.md +0 -373
  71. data/docs/reference/vandal.md +0 -63
  72. data/docs/reference/why.md +0 -13
  73. data/docs/topics/authorization.md +0 -155
  74. data/docs/topics/caching.md +0 -55
  75. data/docs/topics/customizing-sideloads.md +0 -156
  76. data/docs/topics/debugging.md +0 -242
  77. data/docs/topics/error-handling.md +0 -210
  78. data/docs/topics/etags.md +0 -46
  79. data/docs/topics/hopping-relationships.md +0 -149
  80. data/docs/topics/json-attributes.md +0 -77
  81. data/docs/topics/openstruct-models.md +0 -50
  82. data/docs/topics/remote-resources.md +0 -291
  83. data/docs/topics/testing.md +0 -916
  84. data/docs/topics/without-activerecord.md +0 -324
  85. data/docs/tutorial/index.md +0 -58
  86. data/docs/tutorial/step_0.md +0 -107
  87. data/docs/tutorial/step_1.md +0 -199
  88. data/docs/tutorial/step_2.md +0 -312
  89. data/docs/tutorial/step_3.md +0 -142
  90. data/docs/tutorial/step_4.md +0 -135
  91. data/docs/tutorial/step_5.md +0 -69
  92. data/docs/tutorial/step_6.md +0 -82
  93. data/docs/tutorial/step_7.md +0 -205
  94. data/docs/tutorial/step_8.md +0 -128
  95. data/docs/tutorial/step_9.md +0 -171
  96. data/docs/upgrading.md +0 -267
  97. data/website/.gitignore +0 -20
  98. data/website/README.md +0 -43
  99. data/website/docusaurus.config.js +0 -197
  100. data/website/package-lock.json +0 -19474
  101. data/website/package.json +0 -46
  102. data/website/sidebars.js +0 -82
  103. data/website/src/css/custom.css +0 -85
  104. data/website/src/pages/markdown-page.mdx +0 -7
  105. data/website/static/.nojekyll +0 -0
  106. data/website/static/1.13/2019/03/31/graphiti-1-0.html +0 -205
  107. data/website/static/1.13/2019/05/08/graphiti-1-1.html +0 -212
  108. data/website/static/1.13/2019/05/20/graphiti-1-2.html +0 -214
  109. data/website/static/1.13/2019/10/14/tutorial.html +0 -198
  110. data/website/static/1.13/CNAME +0 -1
  111. data/website/static/1.13/README.md +0 -16
  112. data/website/static/1.13/assets/css/syntax.css +0 -60
  113. data/website/static/1.13/assets/favicons/android-chrome-192x192.png +0 -0
  114. data/website/static/1.13/assets/favicons/android-chrome-256x256.png +0 -0
  115. data/website/static/1.13/assets/favicons/apple-touch-icon.png +0 -0
  116. data/website/static/1.13/assets/favicons/browserconfig.xml +0 -9
  117. data/website/static/1.13/assets/favicons/favicon-16x16.png +0 -0
  118. data/website/static/1.13/assets/favicons/favicon-32x32.png +0 -0
  119. data/website/static/1.13/assets/favicons/favicon.ico +0 -0
  120. data/website/static/1.13/assets/favicons/mstile-150x150.png +0 -0
  121. data/website/static/1.13/assets/favicons/safari-pinned-tab.svg +0 -1
  122. data/website/static/1.13/assets/favicons/site.webmanifest +0 -19
  123. data/website/static/1.13/assets/img/backend.gif +0 -0
  124. data/website/static/1.13/assets/img/conformity.png +0 -0
  125. data/website/static/1.13/assets/img/error_payload.png +0 -0
  126. data/website/static/1.13/assets/img/fancy-cushion.png +0 -0
  127. data/website/static/1.13/assets/img/gh.png +0 -0
  128. data/website/static/1.13/assets/img/home-bg.jpg +0 -0
  129. data/website/static/1.13/assets/img/lifecycle.gif +0 -0
  130. data/website/static/1.13/assets/img/logo-500.png +0 -0
  131. data/website/static/1.13/assets/img/logo.png +0 -0
  132. data/website/static/1.13/assets/img/love-graffiti.jpg +0 -0
  133. data/website/static/1.13/assets/img/meta_total_count.png +0 -0
  134. data/website/static/1.13/assets/img/persist.jpg +0 -0
  135. data/website/static/1.13/assets/img/resource.gif +0 -0
  136. data/website/static/1.13/assets/img/rest-graffiti.jpg +0 -0
  137. data/website/static/1.13/assets/img/rest1.gif +0 -0
  138. data/website/static/1.13/assets/img/rest2.gif +0 -0
  139. data/website/static/1.13/assets/img/rest3.gif +0 -0
  140. data/website/static/1.13/assets/img/rethink-rest-graffiti.jpg +0 -0
  141. data/website/static/1.13/assets/img/sunrise.png +0 -0
  142. data/website/static/1.13/assets/img/why.png +0 -0
  143. data/website/static/1.13/assets/js/highlight.pack.js +0 -2
  144. data/website/static/1.13/assets/main.css +0 -15518
  145. data/website/static/1.13/assets/main.css.map +0 -1
  146. data/website/static/1.13/bin/bundle +0 -109
  147. data/website/static/1.13/bin/jekyll +0 -27
  148. data/website/static/1.13/bin/kramdown +0 -27
  149. data/website/static/1.13/bin/listen +0 -27
  150. data/website/static/1.13/bin/rake +0 -27
  151. data/website/static/1.13/bin/rougify +0 -27
  152. data/website/static/1.13/bin/safe_yaml +0 -27
  153. data/website/static/1.13/bin/sass +0 -27
  154. data/website/static/1.13/bin/sass-convert +0 -27
  155. data/website/static/1.13/bin/scss +0 -27
  156. data/website/static/1.13/blog.html +0 -259
  157. data/website/static/1.13/cheatsheet.html +0 -316
  158. data/website/static/1.13/cookbooks/authorization.md +0 -0
  159. data/website/static/1.13/cookbooks/caching.md +0 -0
  160. data/website/static/1.13/cookbooks/customizing-sideloads.html +0 -325
  161. data/website/static/1.13/cookbooks/etags.md +0 -0
  162. data/website/static/1.13/cookbooks/hopping-relationships.html +0 -324
  163. data/website/static/1.13/cookbooks/json_attributes.md +0 -0
  164. data/website/static/1.13/cookbooks/openstruct-models.md +0 -0
  165. data/website/static/1.13/cookbooks/remote-resources.md +0 -0
  166. data/website/static/1.13/cookbooks/without-activerecord.html +0 -510
  167. data/website/static/1.13/features.html +0 -249
  168. data/website/static/1.13/feed.xml +0 -106
  169. data/website/static/1.13/guides/concepts/backends-and-models.html +0 -467
  170. data/website/static/1.13/guides/concepts/debugging.html +0 -440
  171. data/website/static/1.13/guides/concepts/endpoints.html +0 -432
  172. data/website/static/1.13/guides/concepts/error-handling.html +0 -396
  173. data/website/static/1.13/guides/concepts/links.html +0 -501
  174. data/website/static/1.13/guides/concepts/remote-resources.html +0 -536
  175. data/website/static/1.13/guides/concepts/resources.html +0 -2176
  176. data/website/static/1.13/guides/concepts/testing.html +0 -1469
  177. data/website/static/1.13/guides/getting-started/installation.html +0 -420
  178. data/website/static/1.13/guides/graphiti-rails-migration.html +0 -242
  179. data/website/static/1.13/guides/index.html +0 -269
  180. data/website/static/1.13/guides/overview.html +0 -325
  181. data/website/static/1.13/guides/upgrading-2-0.html +0 -193
  182. data/website/static/1.13/guides/upgrading.html +0 -314
  183. data/website/static/1.13/guides/vandal.html +0 -282
  184. data/website/static/1.13/guides/why.html +0 -1121
  185. data/website/static/1.13/index.html +0 -72
  186. data/website/static/1.13/js/authentication.html +0 -295
  187. data/website/static/1.13/js/ddau.html +0 -238
  188. data/website/static/1.13/js/extra-params.html +0 -270
  189. data/website/static/1.13/js/index.html +0 -321
  190. data/website/static/1.13/js/installation.html +0 -637
  191. data/website/static/1.13/js/introduction.html +0 -257
  192. data/website/static/1.13/js/middleware.html +0 -318
  193. data/website/static/1.13/js/reads/fieldsets.html +0 -271
  194. data/website/static/1.13/js/reads/filtering.html +0 -289
  195. data/website/static/1.13/js/reads/includes.html +0 -260
  196. data/website/static/1.13/js/reads/index.html +0 -497
  197. data/website/static/1.13/js/reads/nested-queries.html +0 -353
  198. data/website/static/1.13/js/reads/pagination.html +0 -260
  199. data/website/static/1.13/js/reads/sorting.html +0 -265
  200. data/website/static/1.13/js/reads/statistics.html +0 -289
  201. data/website/static/1.13/js/state-syncing.html +0 -340
  202. data/website/static/1.13/js/writes/deferred.html +0 -296
  203. data/website/static/1.13/js/writes/dirty-tracking.html +0 -399
  204. data/website/static/1.13/js/writes/index.html +0 -391
  205. data/website/static/1.13/js/writes/nested.html +0 -330
  206. data/website/static/1.13/js/writes/validations.html +0 -272
  207. data/website/static/1.13/quickstart.html +0 -660
  208. data/website/static/1.13/template +0 -161
  209. data/website/static/1.13/tutorial/index.html +0 -250
  210. data/website/static/1.13/tutorial/step_0.html +0 -292
  211. data/website/static/1.13/tutorial/step_1.html +0 -517
  212. data/website/static/1.13/tutorial/step_2.html +0 -481
  213. data/website/static/1.13/tutorial/step_3.html +0 -323
  214. data/website/static/1.13/tutorial/step_4.html +0 -318
  215. data/website/static/1.13/tutorial/step_5.html +0 -265
  216. data/website/static/1.13/tutorial/step_6.html +0 -276
  217. data/website/static/1.13/tutorial/step_7.html +0 -390
  218. data/website/static/1.13/tutorial/step_8.html +0 -316
  219. data/website/static/1.13/tutorial/step_9.html +0 -365
  220. data/website/static/CNAME +0 -1
  221. data/website/static/assets/img/error_payload.png +0 -0
  222. data/website/static/assets/img/legacy/legacy-0378a3bb39.png +0 -0
  223. data/website/static/assets/img/legacy/legacy-05bbd3e5fd.png +0 -0
  224. data/website/static/assets/img/legacy/legacy-07aa104495.png +0 -0
  225. data/website/static/assets/img/legacy/legacy-0c75a16b3a.gif +0 -0
  226. data/website/static/assets/img/legacy/legacy-3076df6209.png +0 -0
  227. data/website/static/assets/img/legacy/legacy-7f6889bc89.png +0 -0
  228. data/website/static/assets/img/legacy/legacy-a2cc4363c3.png +0 -0
  229. data/website/static/assets/img/legacy/legacy-f67cfa89ab.png +0 -0
  230. data/website/static/assets/img/meta_total_count.png +0 -0
  231. data/website/static/img/docusaurus-social-card.jpg +0 -0
  232. data/website/static/img/docusaurus.png +0 -0
  233. data/website/static/img/favicon.ico +0 -0
  234. data/website/static/img/logo.png +0 -0
  235. data/website/static/img/logo.svg +0 -1
  236. data/website/static/img/undraw_docusaurus_mountain.svg +0 -171
  237. data/website/static/img/undraw_docusaurus_react.svg +0 -170
  238. data/website/static/img/undraw_docusaurus_tree.svg +0 -40
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphiti
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.beta.7
4
+ version: 2.0.0.beta.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Richmond
@@ -129,30 +129,36 @@ dependencies:
129
129
  name: faraday
130
130
  requirement: !ruby/object:Gem::Requirement
131
131
  requirements:
132
- - - "~>"
132
+ - - ">="
133
133
  - !ruby/object:Gem::Version
134
- version: '0.15'
134
+ version: '2.0'
135
+ - - "<"
136
+ - !ruby/object:Gem::Version
137
+ version: '3'
135
138
  type: :development
136
139
  prerelease: false
137
140
  version_requirements: !ruby/object:Gem::Requirement
138
141
  requirements:
139
- - - "~>"
142
+ - - ">="
140
143
  - !ruby/object:Gem::Version
141
- version: '0.15'
144
+ version: '2.0'
145
+ - - "<"
146
+ - !ruby/object:Gem::Version
147
+ version: '3'
142
148
  - !ruby/object:Gem::Dependency
143
149
  name: kaminari
144
150
  requirement: !ruby/object:Gem::Requirement
145
151
  requirements:
146
152
  - - "~>"
147
153
  - !ruby/object:Gem::Version
148
- version: '0.17'
154
+ version: '1.2'
149
155
  type: :development
150
156
  prerelease: false
151
157
  version_requirements: !ruby/object:Gem::Requirement
152
158
  requirements:
153
159
  - - "~>"
154
160
  - !ruby/object:Gem::Version
155
- version: '0.17'
161
+ version: '1.2'
156
162
  - !ruby/object:Gem::Dependency
157
163
  name: bundler
158
164
  requirement: !ruby/object:Gem::Requirement
@@ -187,14 +193,14 @@ dependencies:
187
193
  requirements:
188
194
  - - "~>"
189
195
  - !ruby/object:Gem::Version
190
- version: 1.4.0
196
+ version: '1.56'
191
197
  type: :development
192
198
  prerelease: false
193
199
  version_requirements: !ruby/object:Gem::Requirement
194
200
  requirements:
195
201
  - - "~>"
196
202
  - !ruby/object:Gem::Version
197
- version: 1.4.0
203
+ version: '1.56'
198
204
  - !ruby/object:Gem::Dependency
199
205
  name: activemodel
200
206
  requirement: !ruby/object:Gem::Requirement
@@ -209,6 +215,20 @@ dependencies:
209
215
  - - ">="
210
216
  - !ruby/object:Gem::Version
211
217
  version: '7.1'
218
+ - !ruby/object:Gem::Dependency
219
+ name: rexml
220
+ requirement: !ruby/object:Gem::Requirement
221
+ requirements:
222
+ - - ">="
223
+ - !ruby/object:Gem::Version
224
+ version: '0'
225
+ type: :development
226
+ prerelease: false
227
+ version_requirements: !ruby/object:Gem::Requirement
228
+ requirements:
229
+ - - ">="
230
+ - !ruby/object:Gem::Version
231
+ version: '0'
212
232
  - !ruby/object:Gem::Dependency
213
233
  name: rspec
214
234
  requirement: !ruby/object:Gem::Requirement
@@ -230,9 +250,11 @@ executables:
230
250
  extensions: []
231
251
  extra_rdoc_files: []
232
252
  files:
253
+ - ".git-blame-ignore-revs"
233
254
  - ".github/probots.yml"
234
255
  - ".github/workflows/ci.yml"
235
256
  - ".github/workflows/docs.yml"
257
+ - ".github/workflows/notify-example-app.yml"
236
258
  - ".github/workflows/release.yml"
237
259
  - ".gitignore"
238
260
  - ".npmrc"
@@ -255,52 +277,6 @@ files:
255
277
  - bin/console
256
278
  - bin/rspec
257
279
  - bin/setup
258
- - docs/concepts/backends-and-models.md
259
- - docs/concepts/endpoints.md
260
- - docs/concepts/links.md
261
- - docs/concepts/overview.md
262
- - docs/concepts/persisting.md
263
- - docs/concepts/relationships.md
264
- - docs/concepts/resources.md
265
- - docs/getting-started/first-api.md
266
- - docs/getting-started/installation.md
267
- - docs/intro.md
268
- - docs/js/authentication.md
269
- - docs/js/ddau.md
270
- - docs/js/extra-params.md
271
- - docs/js/index.md
272
- - docs/js/installation.md
273
- - docs/js/middleware.md
274
- - docs/js/models.md
275
- - docs/js/reads.md
276
- - docs/js/state-syncing.md
277
- - docs/js/writes.md
278
- - docs/reference/vandal.md
279
- - docs/reference/why.md
280
- - docs/topics/authorization.md
281
- - docs/topics/caching.md
282
- - docs/topics/customizing-sideloads.md
283
- - docs/topics/debugging.md
284
- - docs/topics/error-handling.md
285
- - docs/topics/etags.md
286
- - docs/topics/hopping-relationships.md
287
- - docs/topics/json-attributes.md
288
- - docs/topics/openstruct-models.md
289
- - docs/topics/remote-resources.md
290
- - docs/topics/testing.md
291
- - docs/topics/without-activerecord.md
292
- - docs/tutorial/index.md
293
- - docs/tutorial/step_0.md
294
- - docs/tutorial/step_1.md
295
- - docs/tutorial/step_2.md
296
- - docs/tutorial/step_3.md
297
- - docs/tutorial/step_4.md
298
- - docs/tutorial/step_5.md
299
- - docs/tutorial/step_6.md
300
- - docs/tutorial/step_7.md
301
- - docs/tutorial/step_8.md
302
- - docs/tutorial/step_9.md
303
- - docs/upgrading.md
304
280
  - exe/graphiti
305
281
  - gemfiles/.bundle/config
306
282
  - gemfiles/rails_7_1.gemfile
@@ -434,148 +410,6 @@ files:
434
410
  - lib/tasks/graphiti.rake
435
411
  - package-lock.json
436
412
  - package.json
437
- - website/.gitignore
438
- - website/README.md
439
- - website/docusaurus.config.js
440
- - website/package-lock.json
441
- - website/package.json
442
- - website/sidebars.js
443
- - website/src/css/custom.css
444
- - website/src/pages/markdown-page.mdx
445
- - website/static/.nojekyll
446
- - website/static/1.13/2019/03/31/graphiti-1-0.html
447
- - website/static/1.13/2019/05/08/graphiti-1-1.html
448
- - website/static/1.13/2019/05/20/graphiti-1-2.html
449
- - website/static/1.13/2019/10/14/tutorial.html
450
- - website/static/1.13/CNAME
451
- - website/static/1.13/README.md
452
- - website/static/1.13/assets/css/syntax.css
453
- - website/static/1.13/assets/favicons/android-chrome-192x192.png
454
- - website/static/1.13/assets/favicons/android-chrome-256x256.png
455
- - website/static/1.13/assets/favicons/apple-touch-icon.png
456
- - website/static/1.13/assets/favicons/browserconfig.xml
457
- - website/static/1.13/assets/favicons/favicon-16x16.png
458
- - website/static/1.13/assets/favicons/favicon-32x32.png
459
- - website/static/1.13/assets/favicons/favicon.ico
460
- - website/static/1.13/assets/favicons/mstile-150x150.png
461
- - website/static/1.13/assets/favicons/safari-pinned-tab.svg
462
- - website/static/1.13/assets/favicons/site.webmanifest
463
- - website/static/1.13/assets/img/backend.gif
464
- - website/static/1.13/assets/img/conformity.png
465
- - website/static/1.13/assets/img/error_payload.png
466
- - website/static/1.13/assets/img/fancy-cushion.png
467
- - website/static/1.13/assets/img/gh.png
468
- - website/static/1.13/assets/img/home-bg.jpg
469
- - website/static/1.13/assets/img/lifecycle.gif
470
- - website/static/1.13/assets/img/logo-500.png
471
- - website/static/1.13/assets/img/logo.png
472
- - website/static/1.13/assets/img/love-graffiti.jpg
473
- - website/static/1.13/assets/img/meta_total_count.png
474
- - website/static/1.13/assets/img/persist.jpg
475
- - website/static/1.13/assets/img/resource.gif
476
- - website/static/1.13/assets/img/rest-graffiti.jpg
477
- - website/static/1.13/assets/img/rest1.gif
478
- - website/static/1.13/assets/img/rest2.gif
479
- - website/static/1.13/assets/img/rest3.gif
480
- - website/static/1.13/assets/img/rethink-rest-graffiti.jpg
481
- - website/static/1.13/assets/img/sunrise.png
482
- - website/static/1.13/assets/img/why.png
483
- - website/static/1.13/assets/js/highlight.pack.js
484
- - website/static/1.13/assets/main.css
485
- - website/static/1.13/assets/main.css.map
486
- - website/static/1.13/bin/bundle
487
- - website/static/1.13/bin/jekyll
488
- - website/static/1.13/bin/kramdown
489
- - website/static/1.13/bin/listen
490
- - website/static/1.13/bin/rake
491
- - website/static/1.13/bin/rougify
492
- - website/static/1.13/bin/safe_yaml
493
- - website/static/1.13/bin/sass
494
- - website/static/1.13/bin/sass-convert
495
- - website/static/1.13/bin/scss
496
- - website/static/1.13/blog.html
497
- - website/static/1.13/cheatsheet.html
498
- - website/static/1.13/cookbooks/authorization.md
499
- - website/static/1.13/cookbooks/caching.md
500
- - website/static/1.13/cookbooks/customizing-sideloads.html
501
- - website/static/1.13/cookbooks/etags.md
502
- - website/static/1.13/cookbooks/hopping-relationships.html
503
- - website/static/1.13/cookbooks/json_attributes.md
504
- - website/static/1.13/cookbooks/openstruct-models.md
505
- - website/static/1.13/cookbooks/remote-resources.md
506
- - website/static/1.13/cookbooks/without-activerecord.html
507
- - website/static/1.13/features.html
508
- - website/static/1.13/feed.xml
509
- - website/static/1.13/guides/concepts/backends-and-models.html
510
- - website/static/1.13/guides/concepts/debugging.html
511
- - website/static/1.13/guides/concepts/endpoints.html
512
- - website/static/1.13/guides/concepts/error-handling.html
513
- - website/static/1.13/guides/concepts/links.html
514
- - website/static/1.13/guides/concepts/remote-resources.html
515
- - website/static/1.13/guides/concepts/resources.html
516
- - website/static/1.13/guides/concepts/testing.html
517
- - website/static/1.13/guides/getting-started/installation.html
518
- - website/static/1.13/guides/graphiti-rails-migration.html
519
- - website/static/1.13/guides/index.html
520
- - website/static/1.13/guides/overview.html
521
- - website/static/1.13/guides/upgrading-2-0.html
522
- - website/static/1.13/guides/upgrading.html
523
- - website/static/1.13/guides/vandal.html
524
- - website/static/1.13/guides/why.html
525
- - website/static/1.13/index.html
526
- - website/static/1.13/js/authentication.html
527
- - website/static/1.13/js/ddau.html
528
- - website/static/1.13/js/extra-params.html
529
- - website/static/1.13/js/index.html
530
- - website/static/1.13/js/installation.html
531
- - website/static/1.13/js/introduction.html
532
- - website/static/1.13/js/middleware.html
533
- - website/static/1.13/js/reads/fieldsets.html
534
- - website/static/1.13/js/reads/filtering.html
535
- - website/static/1.13/js/reads/includes.html
536
- - website/static/1.13/js/reads/index.html
537
- - website/static/1.13/js/reads/nested-queries.html
538
- - website/static/1.13/js/reads/pagination.html
539
- - website/static/1.13/js/reads/sorting.html
540
- - website/static/1.13/js/reads/statistics.html
541
- - website/static/1.13/js/state-syncing.html
542
- - website/static/1.13/js/writes/deferred.html
543
- - website/static/1.13/js/writes/dirty-tracking.html
544
- - website/static/1.13/js/writes/index.html
545
- - website/static/1.13/js/writes/nested.html
546
- - website/static/1.13/js/writes/validations.html
547
- - website/static/1.13/quickstart.html
548
- - website/static/1.13/template
549
- - website/static/1.13/tutorial/index.html
550
- - website/static/1.13/tutorial/step_0.html
551
- - website/static/1.13/tutorial/step_1.html
552
- - website/static/1.13/tutorial/step_2.html
553
- - website/static/1.13/tutorial/step_3.html
554
- - website/static/1.13/tutorial/step_4.html
555
- - website/static/1.13/tutorial/step_5.html
556
- - website/static/1.13/tutorial/step_6.html
557
- - website/static/1.13/tutorial/step_7.html
558
- - website/static/1.13/tutorial/step_8.html
559
- - website/static/1.13/tutorial/step_9.html
560
- - website/static/CNAME
561
- - website/static/assets/img/error_payload.png
562
- - website/static/assets/img/legacy/legacy-0378a3bb39.png
563
- - website/static/assets/img/legacy/legacy-05bbd3e5fd.png
564
- - website/static/assets/img/legacy/legacy-07aa104495.png
565
- - website/static/assets/img/legacy/legacy-0c75a16b3a.gif
566
- - website/static/assets/img/legacy/legacy-3076df6209.png
567
- - website/static/assets/img/legacy/legacy-7f6889bc89.png
568
- - website/static/assets/img/legacy/legacy-a2cc4363c3.png
569
- - website/static/assets/img/legacy/legacy-f67cfa89ab.png
570
- - website/static/assets/img/meta_total_count.png
571
- - website/static/img/docusaurus-social-card.jpg
572
- - website/static/img/docusaurus.png
573
- - website/static/img/favicon.ico
574
- - website/static/img/logo.png
575
- - website/static/img/logo.svg
576
- - website/static/img/undraw_docusaurus_mountain.svg
577
- - website/static/img/undraw_docusaurus_react.svg
578
- - website/static/img/undraw_docusaurus_tree.svg
579
413
  homepage: https://github.com/graphiti-api/graphiti
580
414
  licenses:
581
415
  - MIT
@@ -1,122 +0,0 @@
1
- ---
2
- title: 'Backends and Models'
3
- ---
4
-
5
- # Backends and Models
6
-
7
- A Resource queries a **Backend** and returns **Models** from what comes back. Graphiti serializes the Models.
8
-
9
- With ActiveRecord those are the same object. `Employee` is both the thing you query and the thing you render, and you can skip most of this page. It matters when they're separate: a search index, an HTTP service, a document store. Then the Backend is whatever you query, and the Model is whatever you hand back.
10
-
11
- ## Scopes {#scopes}
12
-
13
- A **scope** is whatever your backend needs to run a query. Graphiti doesn't care what it is. For ActiveRecord it's an `ActiveRecord::Relation`. Here it's a plain hash:
14
-
15
- ```ruby
16
- class EmployeeResource < ApplicationResource
17
- self.adapter = Graphiti::Adapters::Null
18
-
19
- attribute :name, :string
20
-
21
- def base_scope
22
- { conditions: {}, sort: {} }
23
- end
24
-
25
- filter :name do
26
- eq do |scope, value|
27
- scope[:conditions].merge!(value)
28
- scope
29
- end
30
- end
31
-
32
- sort :name do |scope, direction|
33
- scope[:sort] = { name: direction }
34
- scope
35
- end
36
-
37
- def resolve(scope)
38
- results = Backend.query(scope)
39
- results.map { |result| Employee.new(result) }
40
- end
41
- end
42
- ```
43
-
44
- `base_scope` is the starting point, each `filter` and `sort` block mutates it based on request params, and `resolve` runs the query and returns Models.
45
-
46
- **Every block must return the scope.** Returning the result of `merge!` or an assignment instead of the scope itself is the most common way to break this.
47
-
48
- Writing that per Resource gets old. Once the pattern stabilizes, move it into an [Adapter](/topics/without-activerecord#adapters) and Resources go back to being declarative:
49
-
50
- ```ruby
51
- class EmployeeResource < ApplicationResource
52
- self.adapter = BackendAdapter
53
- attribute :name, :string
54
- end
55
- ```
56
-
57
- ## What a Model has to do {#model-requirements}
58
-
59
- **Respond to `id`, uniquely.** Graphiti uses `model.id` to tell records apart when rendering. Duplicate ids produce wrong output, not an error.
60
-
61
- If the underlying record has no id, generate one:
62
-
63
- ```ruby
64
- def id
65
- @id ||= SecureRandom.uuid
66
- end
67
- ```
68
-
69
- **Respond to its readable attributes.** `attribute :name, :string` calls `model.name`. If your Model doesn't have that method, pass a block instead:
70
-
71
- ```ruby
72
- attribute :name, :string do
73
- @object.full_name
74
- end
75
- ```
76
-
77
- **Include `ActiveModel::Validations` if you want validation errors.** Graphiti checks models on write requests and renders a [JSON:API errors payload](http://jsonapi.org/format/#errors) from `model.errors`. Without it, an invalid model saves silently:
78
-
79
- ```ruby
80
- class Employee
81
- include ActiveModel::Validations
82
-
83
- validates :name, presence: true
84
- end
85
- ```
86
-
87
- ## Writing a Model {#model-implementations}
88
-
89
- Graphiti has no opinion here. A plain class works:
90
-
91
- ```ruby
92
- class Employee
93
- attr_accessor :id, :first_name, :last_name, :age
94
-
95
- def initialize(attrs = {})
96
- attrs.each_pair { |key, value| send(:"#{key}=", value) }
97
- end
98
- end
99
- ```
100
-
101
- [ActiveModel::Model](https://api.rubyonrails.org/classes/ActiveModel/Model.html) gives you the constructor and validations for free:
102
-
103
- ```ruby
104
- class Employee
105
- include ActiveModel::Model
106
-
107
- attr_accessor :id, :first_name, :last_name, :age
108
- end
109
- ```
110
-
111
- [Dry::Struct](https://dry-rb.org/gems/dry-struct) adds type enforcement, and dry-types is already a Graphiti dependency:
112
-
113
- ```ruby
114
- class Employee < Dry::Struct
115
- attribute :id, Types::Integer
116
- attribute :first_name, Types::String
117
- attribute :last_name, Types::String
118
- attribute :age, Types::Integer
119
- end
120
- ```
121
-
122
- `OpenStruct` also works and is what Graphiti uses internally for remote resources, but it fails quietly in ways the others don't. See [OpenStruct Models](/topics/openstruct-models) before reaching for it.
@@ -1,183 +0,0 @@
1
- ---
2
- title: 'Endpoints'
3
- ---
4
-
5
- ## Overview {#overview}
6
-
7
- **Endpoints** expose and customize
8
- [Resources](/concepts/resources).
9
-
10
- Resources themselves can operate completely independently of a request or response:
11
-
12
- ```ruby
13
- employees = EmployeeResource.all({
14
- filter: { title: 'engineer' },
15
- sort: '-created_at',
16
- page: { size: 10 },
17
- include: 'positions.department'
18
- })
19
-
20
- employees.map(&:first_name) # => ['Jane', 'John', ...]
21
- employees.to_json # => { employees: [{ ... }] }
22
- ```
23
-
24
- And Resources connect to other Resources. Our graph of data is defined
25
- **outside** of the actual API.
26
-
27
- Endpoints expose this graph to the world. We might choose to have a `/employees` endpoint that can eager load comments (`?include=comments`), but never expose `/comments` directly. Or, we could do the opposite: expose lazy-loading `/comments`, but disallow eager loading from `/employees`. We can add caching rules, or add an `/exemplary_employees` endpoint with special query overrides.
28
-
29
- Finally, Endpoints are in charge of the [HTTP specification](https://tools.ietf.org/html/rfc2616):
30
- request processing, response codes, caching, MIME types, and so on. If you're thinking
31
- Rails, an Endpoint is the combination of a Route and Controller.
32
-
33
- ### Endpoint Logic {#endpoint-logic}
34
-
35
- Often, you won't need to customize Endpoints - especially if you're
36
- using our [Rails Resource
37
- generator](/concepts/resources#generators). Endpoint logic mostly
38
- concerns:
39
-
40
- * Caching
41
- * Side-effect behavior specific to the endpoint (e.g.: sending a
42
- welcome email from `/users#create` but not `/admin/users#create`)
43
- * Authorization (e.g `before_action`)
44
- * Custom query parameter handling
45
- * Validation handling
46
- * Error handling
47
- * Limiting Resource behavior
48
- * Customizing Resource behavior
49
-
50
- If your logic falls elsewhere, consider a Resource or Model.
51
-
52
- ### Rails Integration {#rails-integration}
53
-
54
- When using Rails, an endpoint is the combination of a Route and
55
- Controller:
56
-
57
- ```ruby
58
- # config/routes.rb
59
- resources :posts, only: [:index]
60
-
61
- # app/controllers/posts_controller.rb
62
- class PostsController < ApplicationController
63
- def index
64
- posts = PostResource.all(params)
65
- respond_with(posts)
66
- end
67
- end
68
- ```
69
-
70
- You'll note that Graphiti hooks into Rails with a mixin (set when using
71
- our application generator):
72
-
73
- ```ruby
74
- class ApplicationController < ActionController::API
75
- include Graphiti::Rails::Controller
76
-
77
- # ... code ...
78
- end
79
- ```
80
-
81
- This gives us [#sideload_allowlist](#sideload-allowlist) and sets the
82
- [context](/concepts/resources#context).
83
-
84
- ## Customizing Resources {#customizing-resources}
85
-
86
- ### Scope Overrides {#scope-overrides}
87
-
88
- One common use case for endpoints is customizing the Resource
89
- [base scope](/concepts/resources#base-scope). This causes a new
90
- "starting point" for query building.
91
-
92
- Consider the endpoints `/posts` (basic CRUD) and `/top_posts`. Though both are associated to PostResource, `/top_posts` ensures that only
93
- Posts with a certain number of upvotes get returned:
94
-
95
- ```ruby
96
- def index
97
- base_scope = Post.where("upvotes > ?", 100)
98
- posts = PostResource.all(params, base_scope)
99
- respond_with(posts)
100
- end
101
- ```
102
-
103
- We're able to reuse all the other logic in PostResource - relationships,
104
- filters, sorts, etc - while only returning "Top Posts".
105
-
106
- ### Sideload Allowlist {#sideload-allowlist}
107
-
108
- Resources define relationships to other resources. But we may not want
109
- all of those relationships exposed at a given endpoint.
110
-
111
- Let's say we've defined relationships:
112
-
113
- `Employee > Position > Department > Hardware > CostHistory`
114
-
115
- It's reasonable to get an Employee, their Positions, and Departments for
116
- those positions in a single request. But is it really valid to *also* pull down
117
- all the hardware, as well as all the historical data on the cost of that hardware,
118
- in a single request? Allowing the entire graph to be pulled down in a single request can cause excessive load on our
119
- servers (and this is probably a better fit for lazy-loading via
120
- [Links](/concepts/links)).
121
-
122
- Let's instead say that if we're entering the graph at `/employees`, the
123
- furthest we can go is Department:
124
-
125
- ```ruby
126
- class EmployeesController < ApplicationController
127
- self.sideload_allowlist = {
128
- index: { positions: 'department' }
129
- }
130
-
131
- # ... code ...
132
- end
133
- ```
134
-
135
- ## Caching {#caching}
136
-
137
- ### Etags {#etags}
138
-
139
- [ETags](https://robots.thoughtbot.com/introduction-to-conditional-http-caching-with-rails) are an important concept that is often overlooked. Etags tell browsers
140
- that the response to a GET request hasn't changed since the last request and
141
- can be safely pulled from the browser cache. If you care about sparse fieldsets,
142
- you should care about ETags - if you're limiting fields to reduce payload size,
143
- how about a payload size of **zero**?
144
-
145
- ETags are set by default in Rails, by checking the response body. This won't prevent queries from executing, but it will save clients from downloading the response again if nothing has changed.
146
-
147
- Let's manually set an ETag:
148
-
149
- ```ruby
150
- def index
151
- posts = PostResource.all(params)
152
-
153
- if stale?(posts.data)
154
- respond_with(posts)
155
- end
156
- end
157
- ```
158
-
159
- From the [documentation on #stale?](https://api.rubyonrails.org/classes/ActionController/ConditionalGet.html#method-i-stale-3F):
160
-
161
- > *In this case last_modified will be set by calling `maximum(:updated_at)` on the collection (the timestamp of the most recently updated record) and the etag by passing the object itself.*
162
-
163
- Also consider the use case where data is ingested hourly. We can avoid a
164
- query altogether by checking when the last ingestion ran:
165
-
166
- ```ruby
167
- def index
168
- if stale?(EmployeeIngestion.last)
169
- employees = EmployeeResource.all(params)
170
- respond_with(employees)
171
- end
172
- end
173
- ```
174
-
175
- > **CAVEAT**: When setting ETags, consider sideloads. In the above examples
176
- > we are checking to see the last update of an Employee, but we may be
177
- > sideloading (and filtering) Positions as well. Use custom endpoints or
178
- > [Sideload Allowlist](#sideload-allowlist) to mitigate this issue.
179
-
180
- ## Testing {#testing}
181
-
182
- If you have custom Endpoint logic, we suggest testing using an [API
183
- Test](/topics/testing#api-tests).