jsonapi-home 1.0.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 +7 -0
- data/README.md +754 -0
- data/Rakefile +12 -0
- data/app/controllers/jsonapi/home/v1/resources_controller.rb +81 -0
- data/app/models/jsonapi/home/v1/resource.rb +134 -0
- data/app/realizers/jsonapi/home/v1/resource_realizer.rb +22 -0
- data/app/serializers/jsonapi/home/v1/resource_serializer.rb +42 -0
- data/config/routes.rb +7 -0
- data/lib/jsonapi-home.rb +3 -0
- data/lib/jsonapi/home.rb +30 -0
- data/lib/jsonapi/home/engine.rb +7 -0
- data/lib/jsonapi/home/inflector.rb +7 -0
- data/lib/jsonapi/home/version.rb +5 -0
- data/lib/jsonapi/home_spec.rb +5 -0
- metadata +197 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 601793a236d6fba997f95f5da8d3ee6ae7db8621078b5a0ad23004718d42d52e
|
4
|
+
data.tar.gz: eef20492884e0a429b1b48a678ce310fd7d9f404ffc4ec5a8984929918b62eb7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 89cd7ba9430afb7b818a6d0a0310349ede9d0803b88f29597b065cad632a667ac5d1b0afb61c3de8377e9381ac744dda17f7b5f32b933db1cae72ef2eafa68a1
|
7
|
+
data.tar.gz: 469784ae1fd60ff93c62144aa93c04b77b08eddc6a09600022e244dbcdbf357061a16e389c9d252de6f653b1b3a00efebd887c56869c27a6bf91772383d2d581
|
data/README.md
ADDED
@@ -0,0 +1,754 @@
|
|
1
|
+
# jsonapi-home
|
2
|
+
|
3
|
+
- [](https://travis-ci.org/krainboltgreene/jsonapi-home)
|
4
|
+
- [](https://rubygems.org/gems/jsonapi-home)
|
5
|
+
- [](https://rubygems.org/gems/jsonapi-home)
|
6
|
+
|
7
|
+
An implementation of an experimental JSON:API-Home specification, which is a combination of the [JSONHome](https://tools.ietf.org/html/draft-nottingham-json-home-06) and [json:api](https://www.jsonapi.org).
|
8
|
+
|
9
|
+
|
10
|
+
## Using
|
11
|
+
|
12
|
+
To start lets mount the engine:
|
13
|
+
|
14
|
+
``` ruby
|
15
|
+
Rails.application.routes.draw do
|
16
|
+
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
|
17
|
+
|
18
|
+
mount JSONAPI::Home::Engine, at: "/"
|
19
|
+
|
20
|
+
namespace :v1 do
|
21
|
+
resources :accounts
|
22
|
+
end
|
23
|
+
|
24
|
+
root to: "pages#landing"
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
28
|
+
This will setup the basic set of home routes and with the following request:
|
29
|
+
|
30
|
+
```
|
31
|
+
* Preparing request to http://localhost:3000/v1/jsonapi-home-resources
|
32
|
+
* Using libcurl/7.54.0 SecureTransport zlib/1.2.8
|
33
|
+
* Enable automatic URL encoding
|
34
|
+
* Enable SSL validation
|
35
|
+
* Enable cookie sending with jar of 0 cookies
|
36
|
+
* Connection 68 seems to be dead!
|
37
|
+
* Closing connection 68
|
38
|
+
* Trying ::1...
|
39
|
+
* TCP_NODELAY set
|
40
|
+
* Connected to localhost (::1) port 3000 (#69)
|
41
|
+
> GET /v1/jsonapi-home-resources HTTP/1.1
|
42
|
+
> Host: localhost:3000
|
43
|
+
> User-Agent: insomnia/5.14.9
|
44
|
+
> Accept: application/vnd.api+json
|
45
|
+
< HTTP/1.1 200 OK
|
46
|
+
< Content-Type: application/json; charset=utf-8
|
47
|
+
< Etag: W/"dfafe86e832bea875149e878c0616b96"
|
48
|
+
< Cache-Control: max-age=0, private, must-revalidate
|
49
|
+
< X-Request-Id: 942ba1cd-2bbc-4902-a89a-8706da7d5533
|
50
|
+
< X-Runtime: 0.037835
|
51
|
+
< Server: WEBrick/1.4.2 (Ruby/2.5.0/2017-12-25)
|
52
|
+
< Date: Sun, 25 Mar 2018 23:07:05 GMT
|
53
|
+
< Content-Length: 1194
|
54
|
+
< Connection: Keep-Alive
|
55
|
+
|
56
|
+
* Received 1194 B chunk
|
57
|
+
* Connection #69 to host localhost left intact
|
58
|
+
```
|
59
|
+
|
60
|
+
You'll get this payload:
|
61
|
+
|
62
|
+
``` json
|
63
|
+
{
|
64
|
+
"data": [
|
65
|
+
{
|
66
|
+
"type": "jsonapi-home-resources",
|
67
|
+
"id": "jsonapi-home-resources-v1-index",
|
68
|
+
"attributes": {
|
69
|
+
"namespace": "jsonapi-home-resources",
|
70
|
+
"version": "v1",
|
71
|
+
"intent": "index",
|
72
|
+
"description": "All discoverable HTTP JSON:API endpoints that this server knows about",
|
73
|
+
"verb": "GET",
|
74
|
+
"href": "/v1/jsonapi-home-resources",
|
75
|
+
"mediatype": "application/vnd.api+json",
|
76
|
+
"created-at": "2018-03-25T16:07:03.039-07:00",
|
77
|
+
"updated-at": "2018-03-25T16:07:05.000-07:00"
|
78
|
+
},
|
79
|
+
"links": {
|
80
|
+
"self": "/jsonapi-home-resources/jsonapi-home-resources-v1-index"
|
81
|
+
},
|
82
|
+
"jsonapi": {
|
83
|
+
"version": "1.0"
|
84
|
+
}
|
85
|
+
},
|
86
|
+
{
|
87
|
+
"type": "jsonapi-home-resources",
|
88
|
+
"id": "jsonapi-home-resources-v1-show",
|
89
|
+
"attributes": {
|
90
|
+
"namespace": "jsonapi-home-resources",
|
91
|
+
"version": "v1",
|
92
|
+
"intent": "show",
|
93
|
+
"description": "All discoverable HTTP JSON:API endpoints that this server knows about",
|
94
|
+
"verb": "GET",
|
95
|
+
"href": "/v1/jsonapi-home-resources/{id}",
|
96
|
+
"mediatype": "application/vnd.api+json",
|
97
|
+
"created-at": "2018-03-25T16:07:03.039-07:00",
|
98
|
+
"updated-at": "2018-03-25T16:07:05.003-07:00"
|
99
|
+
},
|
100
|
+
"links": {
|
101
|
+
"self": "/jsonapi-home-resources/jsonapi-home-resources-v1-show"
|
102
|
+
},
|
103
|
+
"jsonapi": {
|
104
|
+
"version": "1.0"
|
105
|
+
}
|
106
|
+
}
|
107
|
+
],
|
108
|
+
"jsonapi": {
|
109
|
+
"version": "1.0"
|
110
|
+
},
|
111
|
+
"meta": {
|
112
|
+
"endpoint": {
|
113
|
+
"version": "1"
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
```
|
118
|
+
|
119
|
+
You'll notice that we only show our own home routes, we're self-referential! Now we've got to setup your other endpoints:
|
120
|
+
|
121
|
+
``` ruby
|
122
|
+
module V1
|
123
|
+
class AccountsController < V1::ApplicationController
|
124
|
+
discoverable(
|
125
|
+
version: "v1",
|
126
|
+
namespace: "accounts"
|
127
|
+
)
|
128
|
+
|
129
|
+
def index
|
130
|
+
# ...
|
131
|
+
end
|
132
|
+
|
133
|
+
def show
|
134
|
+
# ...
|
135
|
+
end
|
136
|
+
|
137
|
+
def create
|
138
|
+
# ...
|
139
|
+
end
|
140
|
+
|
141
|
+
def update
|
142
|
+
# ...
|
143
|
+
end
|
144
|
+
|
145
|
+
def destroy
|
146
|
+
# ...
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
```
|
151
|
+
|
152
|
+
Which results in this payload:
|
153
|
+
|
154
|
+
```
|
155
|
+
* Preparing request to http://localhost:3000/v1/jsonapi-home-resources
|
156
|
+
* Using libcurl/7.54.0 SecureTransport zlib/1.2.8
|
157
|
+
* Enable automatic URL encoding
|
158
|
+
* Enable SSL validation
|
159
|
+
* Enable cookie sending with jar of 0 cookies
|
160
|
+
* Connection 69 seems to be dead!
|
161
|
+
* Closing connection 69
|
162
|
+
* Trying ::1...
|
163
|
+
* TCP_NODELAY set
|
164
|
+
* Connected to localhost (::1) port 3000 (#70)
|
165
|
+
> GET /v1/jsonapi-home-resources HTTP/1.1
|
166
|
+
> Host: localhost:3000
|
167
|
+
> User-Agent: insomnia/5.14.9
|
168
|
+
> Accept: application/vnd.api+json
|
169
|
+
< HTTP/1.1 200 OK
|
170
|
+
< Content-Type: application/json; charset=utf-8
|
171
|
+
< Etag: W/"4a0ff42059f174ee886ec63b3edeac30"
|
172
|
+
< Cache-Control: max-age=0, private, must-revalidate
|
173
|
+
< X-Request-Id: 3afadc55-ed06-4811-8500-939dee3271bd
|
174
|
+
< X-Runtime: 0.125346
|
175
|
+
< Server: WEBrick/1.4.2 (Ruby/2.5.0/2017-12-25)
|
176
|
+
< Date: Mon, 26 Mar 2018 01:28:41 GMT
|
177
|
+
< Content-Length: 5591
|
178
|
+
< Connection: Keep-Alive
|
179
|
+
|
180
|
+
* Received 5.5 KB chunk
|
181
|
+
* Connection #70 to host localhost left intact
|
182
|
+
```
|
183
|
+
|
184
|
+
``` json
|
185
|
+
{
|
186
|
+
"data": [
|
187
|
+
{
|
188
|
+
"type": "jsonapi-home-resources",
|
189
|
+
"id": "accounts-v1-index",
|
190
|
+
"attributes": {
|
191
|
+
"namespace": "accounts",
|
192
|
+
"version": "v1",
|
193
|
+
"intent": "index",
|
194
|
+
"description": "A JSON:API resource as defined at https://www.jsonapi.org",
|
195
|
+
"deprecated": null,
|
196
|
+
"verb": "GET",
|
197
|
+
"href": "/v1/accounts",
|
198
|
+
"mediatype": "application/vnd.api+json",
|
199
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
200
|
+
"updated-at": "2018-03-26T00:17:31.023-07:00"
|
201
|
+
},
|
202
|
+
"links": {
|
203
|
+
"self": "/jsonapi-home-resources/accounts-v1-index"
|
204
|
+
},
|
205
|
+
"jsonapi": {
|
206
|
+
"version": "v1"
|
207
|
+
}
|
208
|
+
},
|
209
|
+
{
|
210
|
+
"type": "jsonapi-home-resources",
|
211
|
+
"id": "accounts-v1-create",
|
212
|
+
"attributes": {
|
213
|
+
"namespace": "accounts",
|
214
|
+
"version": "v1",
|
215
|
+
"intent": "create",
|
216
|
+
"description": "A JSON:API resource as defined at https://www.jsonapi.org",
|
217
|
+
"deprecated": null,
|
218
|
+
"verb": "POST",
|
219
|
+
"href": "/v1/accounts",
|
220
|
+
"mediatype": "application/vnd.api+json",
|
221
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
222
|
+
"updated-at": "2018-03-26T00:17:31.038-07:00"
|
223
|
+
},
|
224
|
+
"links": {
|
225
|
+
"self": "/jsonapi-home-resources/accounts-v1-create"
|
226
|
+
},
|
227
|
+
"jsonapi": {
|
228
|
+
"version": "v1"
|
229
|
+
}
|
230
|
+
},
|
231
|
+
{
|
232
|
+
"type": "jsonapi-home-resources",
|
233
|
+
"id": "accounts-v1-new",
|
234
|
+
"attributes": {
|
235
|
+
"namespace": "accounts",
|
236
|
+
"version": "v1",
|
237
|
+
"intent": "new",
|
238
|
+
"description": "A JSON:API resource as defined at https://www.jsonapi.org",
|
239
|
+
"deprecated": null,
|
240
|
+
"verb": "GET",
|
241
|
+
"href": "/v1/accounts/new",
|
242
|
+
"mediatype": "application/vnd.api+json",
|
243
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
244
|
+
"updated-at": "2018-03-26T00:17:31.056-07:00"
|
245
|
+
},
|
246
|
+
"links": {
|
247
|
+
"self": "/jsonapi-home-resources/accounts-v1-new"
|
248
|
+
},
|
249
|
+
"jsonapi": {
|
250
|
+
"version": "v1"
|
251
|
+
}
|
252
|
+
},
|
253
|
+
{
|
254
|
+
"type": "jsonapi-home-resources",
|
255
|
+
"id": "accounts-v1-edit",
|
256
|
+
"attributes": {
|
257
|
+
"namespace": "accounts",
|
258
|
+
"version": "v1",
|
259
|
+
"intent": "edit",
|
260
|
+
"description": "A JSON:API resource as defined at https://www.jsonapi.org",
|
261
|
+
"deprecated": null,
|
262
|
+
"verb": "GET",
|
263
|
+
"href": "/v1/accounts/{id}/edit",
|
264
|
+
"mediatype": "application/vnd.api+json",
|
265
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
266
|
+
"updated-at": "2018-03-26T00:17:31.067-07:00"
|
267
|
+
},
|
268
|
+
"links": {
|
269
|
+
"self": "/jsonapi-home-resources/accounts-v1-edit"
|
270
|
+
},
|
271
|
+
"jsonapi": {
|
272
|
+
"version": "v1"
|
273
|
+
}
|
274
|
+
},
|
275
|
+
{
|
276
|
+
"type": "jsonapi-home-resources",
|
277
|
+
"id": "accounts-v1-show",
|
278
|
+
"attributes": {
|
279
|
+
"namespace": "accounts",
|
280
|
+
"version": "v1",
|
281
|
+
"intent": "show",
|
282
|
+
"description": "A JSON:API resource as defined at https://www.jsonapi.org",
|
283
|
+
"deprecated": null,
|
284
|
+
"verb": "GET",
|
285
|
+
"href": "/v1/accounts/{id}",
|
286
|
+
"mediatype": "application/vnd.api+json",
|
287
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
288
|
+
"updated-at": "2018-03-26T00:17:31.073-07:00"
|
289
|
+
},
|
290
|
+
"links": {
|
291
|
+
"self": "/jsonapi-home-resources/accounts-v1-show"
|
292
|
+
},
|
293
|
+
"jsonapi": {
|
294
|
+
"version": "v1"
|
295
|
+
}
|
296
|
+
},
|
297
|
+
{
|
298
|
+
"type": "jsonapi-home-resources",
|
299
|
+
"id": "accounts-v1-update",
|
300
|
+
"attributes": {
|
301
|
+
"namespace": "accounts",
|
302
|
+
"version": "v1",
|
303
|
+
"intent": "update",
|
304
|
+
"description": "A JSON:API resource as defined at https://www.jsonapi.org",
|
305
|
+
"deprecated": null,
|
306
|
+
"verb": "PATCH",
|
307
|
+
"href": "/v1/accounts/{id}",
|
308
|
+
"mediatype": "application/vnd.api+json",
|
309
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
310
|
+
"updated-at": "2018-03-26T00:17:31.076-07:00"
|
311
|
+
},
|
312
|
+
"links": {
|
313
|
+
"self": "/jsonapi-home-resources/accounts-v1-update"
|
314
|
+
},
|
315
|
+
"jsonapi": {
|
316
|
+
"version": "v1"
|
317
|
+
}
|
318
|
+
},
|
319
|
+
{
|
320
|
+
"type": "jsonapi-home-resources",
|
321
|
+
"id": "accounts-v1-update",
|
322
|
+
"attributes": {
|
323
|
+
"namespace": "accounts",
|
324
|
+
"version": "v1",
|
325
|
+
"intent": "update",
|
326
|
+
"description": "A JSON:API resource as defined at https://www.jsonapi.org",
|
327
|
+
"deprecated": null,
|
328
|
+
"verb": "PUT",
|
329
|
+
"href": "/v1/accounts/{id}",
|
330
|
+
"mediatype": "application/vnd.api+json",
|
331
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
332
|
+
"updated-at": "2018-03-26T00:17:31.080-07:00"
|
333
|
+
},
|
334
|
+
"links": {
|
335
|
+
"self": "/jsonapi-home-resources/accounts-v1-update"
|
336
|
+
},
|
337
|
+
"jsonapi": {
|
338
|
+
"version": "v1"
|
339
|
+
}
|
340
|
+
},
|
341
|
+
{
|
342
|
+
"type": "jsonapi-home-resources",
|
343
|
+
"id": "accounts-v1-destroy",
|
344
|
+
"attributes": {
|
345
|
+
"namespace": "accounts",
|
346
|
+
"version": "v1",
|
347
|
+
"intent": "destroy",
|
348
|
+
"description": "A JSON:API resource as defined at https://www.jsonapi.org",
|
349
|
+
"deprecated": null,
|
350
|
+
"verb": "DELETE",
|
351
|
+
"href": "/v1/accounts/{id}",
|
352
|
+
"mediatype": "application/vnd.api+json",
|
353
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
354
|
+
"updated-at": "2018-03-26T00:17:31.083-07:00"
|
355
|
+
},
|
356
|
+
"links": {
|
357
|
+
"self": "/jsonapi-home-resources/accounts-v1-destroy"
|
358
|
+
},
|
359
|
+
"jsonapi": {
|
360
|
+
"version": "v1"
|
361
|
+
}
|
362
|
+
},
|
363
|
+
{
|
364
|
+
"type": "jsonapi-home-resources",
|
365
|
+
"id": "posts-v1-index",
|
366
|
+
"attributes": {
|
367
|
+
"namespace": "posts",
|
368
|
+
"version": "v1",
|
369
|
+
"intent": "index",
|
370
|
+
"description": "Oh hi, mark",
|
371
|
+
"deprecated": false,
|
372
|
+
"verb": "GET",
|
373
|
+
"href": "https://www.example.com/v1/posts",
|
374
|
+
"mediatype": "application/vnd.api+json",
|
375
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
376
|
+
"updated-at": "2018-03-26T00:17:31.088-07:00"
|
377
|
+
},
|
378
|
+
"links": {
|
379
|
+
"self": "/jsonapi-home-resources/posts-v1-index"
|
380
|
+
},
|
381
|
+
"jsonapi": {
|
382
|
+
"version": "v1"
|
383
|
+
},
|
384
|
+
"meta": {
|
385
|
+
"documentation": {
|
386
|
+
"href": "https://www.schema.org"
|
387
|
+
}
|
388
|
+
}
|
389
|
+
},
|
390
|
+
{
|
391
|
+
"type": "jsonapi-home-resources",
|
392
|
+
"id": "posts-v1-update",
|
393
|
+
"attributes": {
|
394
|
+
"namespace": "posts",
|
395
|
+
"version": "v1",
|
396
|
+
"intent": "update",
|
397
|
+
"description": "Oh hi, mark",
|
398
|
+
"deprecated": false,
|
399
|
+
"verb": "PATCH",
|
400
|
+
"href": "https://www.example.com/v1/posts/{id}",
|
401
|
+
"mediatype": "application/vnd.api+json",
|
402
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
403
|
+
"updated-at": "2018-03-26T00:17:31.093-07:00"
|
404
|
+
},
|
405
|
+
"links": {
|
406
|
+
"self": "/jsonapi-home-resources/posts-v1-update"
|
407
|
+
},
|
408
|
+
"jsonapi": {
|
409
|
+
"version": "v1"
|
410
|
+
},
|
411
|
+
"meta": {
|
412
|
+
"documentation": {
|
413
|
+
"href": "https://www.schema.org"
|
414
|
+
}
|
415
|
+
}
|
416
|
+
},
|
417
|
+
{
|
418
|
+
"type": "jsonapi-home-resources",
|
419
|
+
"id": "posts-v1-update",
|
420
|
+
"attributes": {
|
421
|
+
"namespace": "posts",
|
422
|
+
"version": "v1",
|
423
|
+
"intent": "update",
|
424
|
+
"description": "Oh hi, mark",
|
425
|
+
"deprecated": false,
|
426
|
+
"verb": "PUT",
|
427
|
+
"href": "https://www.example.com/v1/posts/{id}",
|
428
|
+
"mediatype": "application/vnd.api+json",
|
429
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
430
|
+
"updated-at": "2018-03-26T00:17:31.097-07:00"
|
431
|
+
},
|
432
|
+
"links": {
|
433
|
+
"self": "/jsonapi-home-resources/posts-v1-update"
|
434
|
+
},
|
435
|
+
"jsonapi": {
|
436
|
+
"version": "v1"
|
437
|
+
},
|
438
|
+
"meta": {
|
439
|
+
"documentation": {
|
440
|
+
"href": "https://www.schema.org"
|
441
|
+
}
|
442
|
+
}
|
443
|
+
},
|
444
|
+
{
|
445
|
+
"type": "jsonapi-home-resources",
|
446
|
+
"id": "posts-v1-destroy",
|
447
|
+
"attributes": {
|
448
|
+
"namespace": "posts",
|
449
|
+
"version": "v1",
|
450
|
+
"intent": "destroy",
|
451
|
+
"description": "Oh hi, mark",
|
452
|
+
"deprecated": false,
|
453
|
+
"verb": "DELETE",
|
454
|
+
"href": "https://www.example.com/v1/posts/{id}",
|
455
|
+
"mediatype": "application/vnd.api+json",
|
456
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
457
|
+
"updated-at": "2018-03-26T00:17:31.101-07:00"
|
458
|
+
},
|
459
|
+
"links": {
|
460
|
+
"self": "/jsonapi-home-resources/posts-v1-destroy"
|
461
|
+
},
|
462
|
+
"jsonapi": {
|
463
|
+
"version": "v1"
|
464
|
+
},
|
465
|
+
"meta": {
|
466
|
+
"documentation": {
|
467
|
+
"href": "https://www.schema.org"
|
468
|
+
}
|
469
|
+
}
|
470
|
+
},
|
471
|
+
{
|
472
|
+
"type": "jsonapi-home-resources",
|
473
|
+
"id": "accounts-v1-index",
|
474
|
+
"attributes": {
|
475
|
+
"namespace": "accounts",
|
476
|
+
"version": "v1",
|
477
|
+
"intent": "index",
|
478
|
+
"description": "A JSON:API resource as defined at https://www.jsonapi.org",
|
479
|
+
"deprecated": null,
|
480
|
+
"verb": "GET",
|
481
|
+
"href": "/",
|
482
|
+
"mediatype": "application/vnd.api+json",
|
483
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
484
|
+
"updated-at": "2018-03-26T00:17:31.108-07:00"
|
485
|
+
},
|
486
|
+
"links": {
|
487
|
+
"self": "/jsonapi-home-resources/accounts-v1-index"
|
488
|
+
},
|
489
|
+
"jsonapi": {
|
490
|
+
"version": "v1"
|
491
|
+
}
|
492
|
+
},
|
493
|
+
{
|
494
|
+
"type": "jsonapi-home-resources",
|
495
|
+
"id": "jsonapi-home-resources-v1-index",
|
496
|
+
"attributes": {
|
497
|
+
"namespace": "jsonapi-home-resources",
|
498
|
+
"version": "v1",
|
499
|
+
"intent": "index",
|
500
|
+
"description": "All discoverable HTTP JSON:API endpoints that this server knows about",
|
501
|
+
"deprecated": null,
|
502
|
+
"verb": "GET",
|
503
|
+
"href": "/v1/jsonapi-home-resources",
|
504
|
+
"mediatype": "application/vnd.api+json",
|
505
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
506
|
+
"updated-at": "2018-03-26T00:17:31.111-07:00"
|
507
|
+
},
|
508
|
+
"links": {
|
509
|
+
"self": "/jsonapi-home-resources/jsonapi-home-resources-v1-index"
|
510
|
+
},
|
511
|
+
"jsonapi": {
|
512
|
+
"version": "v1"
|
513
|
+
},
|
514
|
+
"meta": {
|
515
|
+
"documentation": {
|
516
|
+
"href": "https://github.com/krainboltgreene/jsonapi-home.rb"
|
517
|
+
}
|
518
|
+
}
|
519
|
+
},
|
520
|
+
{
|
521
|
+
"type": "jsonapi-home-resources",
|
522
|
+
"id": "jsonapi-home-resources-v1-show",
|
523
|
+
"attributes": {
|
524
|
+
"namespace": "jsonapi-home-resources",
|
525
|
+
"version": "v1",
|
526
|
+
"intent": "show",
|
527
|
+
"description": "All discoverable HTTP JSON:API endpoints that this server knows about",
|
528
|
+
"deprecated": null,
|
529
|
+
"verb": "GET",
|
530
|
+
"href": "/v1/jsonapi-home-resources/{id}",
|
531
|
+
"mediatype": "application/vnd.api+json",
|
532
|
+
"created-at": "2018-03-26T00:17:28.693-07:00",
|
533
|
+
"updated-at": "2018-03-26T00:17:31.115-07:00"
|
534
|
+
},
|
535
|
+
"links": {
|
536
|
+
"self": "/jsonapi-home-resources/jsonapi-home-resources-v1-show"
|
537
|
+
},
|
538
|
+
"jsonapi": {
|
539
|
+
"version": "v1"
|
540
|
+
},
|
541
|
+
"meta": {
|
542
|
+
"documentation": {
|
543
|
+
"href": "https://github.com/krainboltgreene/jsonapi-home.rb"
|
544
|
+
}
|
545
|
+
}
|
546
|
+
}
|
547
|
+
],
|
548
|
+
"jsonapi": {
|
549
|
+
"version": "1.0"
|
550
|
+
},
|
551
|
+
"meta": {
|
552
|
+
"endpoint": {
|
553
|
+
"version": "1"
|
554
|
+
}
|
555
|
+
}
|
556
|
+
}
|
557
|
+
```
|
558
|
+
|
559
|
+
You can also inquire about individual endpoints:
|
560
|
+
|
561
|
+
```
|
562
|
+
* Preparing request to http://localhost:3000/v1/jsonapi-home-resources/accounts-v1-destroy
|
563
|
+
* Using libcurl/7.54.0 SecureTransport zlib/1.2.8
|
564
|
+
* Enable automatic URL encoding
|
565
|
+
* Enable SSL validation
|
566
|
+
* Enable cookie sending with jar of 0 cookies
|
567
|
+
* Connection 70 seems to be dead!
|
568
|
+
* Closing connection 70
|
569
|
+
* Trying ::1...
|
570
|
+
* TCP_NODELAY set
|
571
|
+
* Connected to localhost (::1) port 3000 (#71)
|
572
|
+
> GET /v1/jsonapi-home-resources/accounts-v1-destroy HTTP/1.1
|
573
|
+
> Host: localhost:3000
|
574
|
+
> User-Agent: insomnia/5.14.9
|
575
|
+
> Accept: application/vnd.api+json
|
576
|
+
< HTTP/1.1 200 OK
|
577
|
+
< Content-Type: application/json; charset=utf-8
|
578
|
+
< Etag: W/"ea14613f3daa0a8e2edfff922d88ef95"
|
579
|
+
< Cache-Control: max-age=0, private, must-revalidate
|
580
|
+
< X-Request-Id: d16732df-3f7f-434b-a4da-d08b7ab27ee6
|
581
|
+
< X-Runtime: 0.022813
|
582
|
+
< Server: WEBrick/1.4.2 (Ruby/2.5.0/2017-12-25)
|
583
|
+
< Date: Mon, 26 Mar 2018 01:31:12 GMT
|
584
|
+
< Content-Length: 571
|
585
|
+
< Connection: Keep-Alive
|
586
|
+
|
587
|
+
* Received 571 B chunk
|
588
|
+
* Connection #71 to host localhost left intact
|
589
|
+
```
|
590
|
+
|
591
|
+
``` json
|
592
|
+
{
|
593
|
+
"data": {
|
594
|
+
"type": "jsonapi-home-resources",
|
595
|
+
"id": "accounts-v1-destroy",
|
596
|
+
"attributes": {
|
597
|
+
"namespace": "accounts",
|
598
|
+
"version": "v1",
|
599
|
+
"intent": "destroy",
|
600
|
+
"description": "A JSON:API resource as defined at https://www.jsonapi.org",
|
601
|
+
"verb": "DELETE",
|
602
|
+
"href": "/v1/accounts/{id}",
|
603
|
+
"mediatype": "application/vnd.api+json",
|
604
|
+
"created-at": "2018-03-25T18:28:37.776-07:00",
|
605
|
+
"updated-at": "2018-03-25T18:31:12.294-07:00"
|
606
|
+
},
|
607
|
+
"links": {
|
608
|
+
"self": "/jsonapi-home-resources/accounts-v1-destroy"
|
609
|
+
},
|
610
|
+
"jsonapi": {
|
611
|
+
"version": "1.0"
|
612
|
+
}
|
613
|
+
},
|
614
|
+
"jsonapi": {
|
615
|
+
"version": "1.0"
|
616
|
+
},
|
617
|
+
"meta": {
|
618
|
+
"endpoint": {
|
619
|
+
"version": "1"
|
620
|
+
}
|
621
|
+
}
|
622
|
+
}
|
623
|
+
```
|
624
|
+
|
625
|
+
Because it's jsonapi.org you can use all the normal interfaces.
|
626
|
+
|
627
|
+
### Custom URL Location
|
628
|
+
|
629
|
+
**By default you will see resources have a root url of whatever returns from `root_path`.**
|
630
|
+
|
631
|
+
If you need a different value you can do one of two things:
|
632
|
+
|
633
|
+
- You can set up a `HOME_LOCATION` ENV variable which is a protocol+hostname[+suffix] combination where your endpoints exist:
|
634
|
+
```
|
635
|
+
HOME_LOCATION=https://origin.example.com
|
636
|
+
```
|
637
|
+
- If you need an individual endpoint to have this value, try:
|
638
|
+
``` ruby
|
639
|
+
module V1
|
640
|
+
class AccountsController < V1::ApplicationController
|
641
|
+
discoverable(
|
642
|
+
version: "v1",
|
643
|
+
namespace: "accounts",
|
644
|
+
location: "http://special.example.com"
|
645
|
+
)
|
646
|
+
end
|
647
|
+
end
|
648
|
+
```
|
649
|
+
|
650
|
+
### Custom Description
|
651
|
+
|
652
|
+
If you want you can overwrite the description that comes with every endpoint to provide context:
|
653
|
+
|
654
|
+
``` ruby
|
655
|
+
module V1
|
656
|
+
class AccountsController < V1::ApplicationController
|
657
|
+
discoverable(
|
658
|
+
version: "v1",
|
659
|
+
namespace: "accounts",
|
660
|
+
description: "The accounts resource is being removed on the 5th of march"
|
661
|
+
)
|
662
|
+
end
|
663
|
+
end
|
664
|
+
```
|
665
|
+
|
666
|
+
### Deprecated
|
667
|
+
|
668
|
+
To provide a hint to clients you can also set the entire endpoint as deprecated:
|
669
|
+
|
670
|
+
``` ruby
|
671
|
+
module V1
|
672
|
+
class AccountsController < V1::ApplicationController
|
673
|
+
discoverable(
|
674
|
+
version: "v1",
|
675
|
+
namespace: "accounts",
|
676
|
+
deprecated: true,
|
677
|
+
)
|
678
|
+
end
|
679
|
+
end
|
680
|
+
```
|
681
|
+
|
682
|
+
Or specific endpoints:
|
683
|
+
|
684
|
+
``` ruby
|
685
|
+
module V1
|
686
|
+
class AccountsController < V1::ApplicationController
|
687
|
+
discoverable(
|
688
|
+
version: "v1",
|
689
|
+
namespace: "accounts",
|
690
|
+
deprecated: {
|
691
|
+
index: true
|
692
|
+
},
|
693
|
+
)
|
694
|
+
end
|
695
|
+
end
|
696
|
+
```
|
697
|
+
|
698
|
+
### Documentation HREF
|
699
|
+
|
700
|
+
Every endpoint can link to the human documentation for that endpoint:
|
701
|
+
|
702
|
+
``` ruby
|
703
|
+
module V1
|
704
|
+
class AccountsController < V1::ApplicationController
|
705
|
+
discoverable(
|
706
|
+
version: "v1",
|
707
|
+
namespace: "accounts",
|
708
|
+
documentation: "https://documentation.example.com"
|
709
|
+
)
|
710
|
+
end
|
711
|
+
end
|
712
|
+
```
|
713
|
+
|
714
|
+
### JSONAPI Version
|
715
|
+
|
716
|
+
Finally you can specify the specific version of JSON:API this endpoint uses:
|
717
|
+
|
718
|
+
``` ruby
|
719
|
+
module V1
|
720
|
+
class AccountsController < V1::ApplicationController
|
721
|
+
discoverable(
|
722
|
+
version: "v1",
|
723
|
+
namespace: "accounts",
|
724
|
+
jsonapi_version: "1.1"
|
725
|
+
)
|
726
|
+
end
|
727
|
+
end
|
728
|
+
```
|
729
|
+
|
730
|
+
Of course, these are all just descriptive. jsonapi-home does not enforce these configurations.
|
731
|
+
|
732
|
+
## Installing
|
733
|
+
|
734
|
+
Add this line to your application's Gemfile:
|
735
|
+
|
736
|
+
gem "jsonapi-home", "1.0.0"
|
737
|
+
|
738
|
+
And then execute:
|
739
|
+
|
740
|
+
$ bundle
|
741
|
+
|
742
|
+
Or install it yourself with:
|
743
|
+
|
744
|
+
$ gem install jsonapi-home
|
745
|
+
|
746
|
+
|
747
|
+
## Contributing
|
748
|
+
|
749
|
+
1. Read the [Code of Conduct](/CONDUCT.md)
|
750
|
+
2. Fork it
|
751
|
+
3. Create your feature branch (`git checkout -b my-new-feature`)
|
752
|
+
4. Commit your changes (`git commit -am 'Add some feature'`)
|
753
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
754
|
+
6. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rspec/core/rake_task"
|
5
|
+
|
6
|
+
desc "Run all the tests in spec"
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |let|
|
8
|
+
let.pattern = "lib/**{,/*/**}/*_spec.rb"
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Default: run tests"
|
12
|
+
task default: :spec
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module JSONAPI
|
2
|
+
module Home
|
3
|
+
module V1
|
4
|
+
class ResourcesController < ::ApplicationController
|
5
|
+
include JSONAPI::Home
|
6
|
+
|
7
|
+
discoverable(
|
8
|
+
version: "v1",
|
9
|
+
namespace: "jsonapi-home-resources",
|
10
|
+
description: "All discoverable HTTP JSON:API endpoints that this server knows about",
|
11
|
+
documentation: "https://github.com/krainboltgreene/jsonapi-home.rb"
|
12
|
+
)
|
13
|
+
|
14
|
+
def index
|
15
|
+
realization = JSONAPI::Realizer.index(
|
16
|
+
params,
|
17
|
+
headers: request.headers,
|
18
|
+
type: :jsonapi_home_resources
|
19
|
+
)
|
20
|
+
|
21
|
+
render json: serialize(realization)
|
22
|
+
end
|
23
|
+
|
24
|
+
def show
|
25
|
+
realization = JSONAPI::Realizer.show(
|
26
|
+
params,
|
27
|
+
headers: request.headers,
|
28
|
+
type: :jsonapi_home_resources
|
29
|
+
)
|
30
|
+
|
31
|
+
render json: serialize(realization)
|
32
|
+
end
|
33
|
+
|
34
|
+
private def serialize(realization)
|
35
|
+
JSONAPI::Serializer.serialize(
|
36
|
+
if realization.respond_to?(:models) then realization.models else realization.model end,
|
37
|
+
is_collection: realization.respond_to?(:models),
|
38
|
+
meta: serialized_metadata,
|
39
|
+
links: serialized_links,
|
40
|
+
jsonapi: serialized_jsonapi,
|
41
|
+
fields: if realization.fields.any? then realization.fields end,
|
42
|
+
include: if realization.includes.any? then realization.includes end
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
private def serialized_metadata
|
47
|
+
{
|
48
|
+
endpoint: {
|
49
|
+
version: "1"
|
50
|
+
}
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
private def serialized_links
|
55
|
+
[
|
56
|
+
if instance_variable_get(:@jsonapi_home_location)
|
57
|
+
{
|
58
|
+
home: {
|
59
|
+
href: "#{instance_variable_get(:@jsonapi_home_location)}/jsonapi-home-resources"
|
60
|
+
}
|
61
|
+
}
|
62
|
+
end,
|
63
|
+
if ENV.key?("HOME_DOCUMENTATION_HREF")
|
64
|
+
{
|
65
|
+
documentation: {
|
66
|
+
href: "#{ENV.fetch("HOME_DOCUMENTATION_HREF")}"
|
67
|
+
}
|
68
|
+
}
|
69
|
+
end,
|
70
|
+
].compact.reduce(&:merge)
|
71
|
+
end
|
72
|
+
|
73
|
+
private def serialized_jsonapi
|
74
|
+
{
|
75
|
+
version: "1.0"
|
76
|
+
}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module JSONAPI
|
2
|
+
module Home
|
3
|
+
module V1
|
4
|
+
class Resource
|
5
|
+
include ActiveModel::Model
|
6
|
+
|
7
|
+
CREATED_AT = Time.now
|
8
|
+
private_constant :CREATED_AT
|
9
|
+
|
10
|
+
attr_reader :route
|
11
|
+
private :route
|
12
|
+
|
13
|
+
def self.all
|
14
|
+
routes.map(&method(:new)).select(&:valid?)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.where(attributes)
|
18
|
+
all.where(attributes)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.fetch(id)
|
22
|
+
all.index_by(&:id).fetch(id)
|
23
|
+
end
|
24
|
+
|
25
|
+
private_class_method def self.routes
|
26
|
+
[
|
27
|
+
*Rails.application.routes.routes.to_a,
|
28
|
+
*Rails::Engine.subclasses.map(&:instance).map(&:routes).map(&:routes).map(&:to_a).flatten
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(route)
|
33
|
+
@route = route
|
34
|
+
end
|
35
|
+
|
36
|
+
def id
|
37
|
+
"#{namespace}-#{version}-#{intent}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def intent
|
41
|
+
defaults.fetch(:action)
|
42
|
+
end
|
43
|
+
|
44
|
+
def namespace
|
45
|
+
configuration.fetch(:namespace)
|
46
|
+
end
|
47
|
+
|
48
|
+
def version
|
49
|
+
configuration.fetch(:version)
|
50
|
+
end
|
51
|
+
|
52
|
+
def description
|
53
|
+
configuration.fetch(:description)
|
54
|
+
end
|
55
|
+
|
56
|
+
def deprecated
|
57
|
+
if configuration.fetch(:deprecated).respond_to?(:fetch)
|
58
|
+
configuration.fetch(:deprecated).fetch(action, nil)
|
59
|
+
else
|
60
|
+
configuration.fetch(:deprecated)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def documentation
|
65
|
+
configuration.fetch(:documentation)
|
66
|
+
end
|
67
|
+
|
68
|
+
def jsonapi_version
|
69
|
+
configuration.fetch(:version)
|
70
|
+
end
|
71
|
+
|
72
|
+
def verb
|
73
|
+
route.verb
|
74
|
+
end
|
75
|
+
|
76
|
+
def href
|
77
|
+
File.join(location, path)
|
78
|
+
end
|
79
|
+
|
80
|
+
def location
|
81
|
+
configuration.fetch(:location) ||
|
82
|
+
ENV.fetch("HOME_LOCATION", nil) ||
|
83
|
+
Rails.application.routes.url_helpers.root_path
|
84
|
+
end
|
85
|
+
|
86
|
+
def mediatype
|
87
|
+
JSONAPI::MEDIA_TYPE
|
88
|
+
end
|
89
|
+
|
90
|
+
def created_at
|
91
|
+
CREATED_AT
|
92
|
+
end
|
93
|
+
|
94
|
+
def updated_at
|
95
|
+
Time.now
|
96
|
+
end
|
97
|
+
|
98
|
+
def valid?
|
99
|
+
!route.internal && defaults.any? && controller.present? && configuration
|
100
|
+
end
|
101
|
+
|
102
|
+
private def payload
|
103
|
+
route.parts.without(:format).map {|part| {part => "{#{part}}"}}.reduce(:merge) || {}
|
104
|
+
end
|
105
|
+
|
106
|
+
private def path
|
107
|
+
URI.decode(route.format(payload))
|
108
|
+
end
|
109
|
+
|
110
|
+
private def controller
|
111
|
+
controller_name.constantize
|
112
|
+
rescue NameError => exception
|
113
|
+
Rails.logger.debug("jsonapi-home saw a route and tried to find #{controller_name}")
|
114
|
+
end
|
115
|
+
|
116
|
+
private def action
|
117
|
+
defaults.fetch(:action)
|
118
|
+
end
|
119
|
+
|
120
|
+
private def controller_name
|
121
|
+
"#{defaults.fetch(:controller).classify.pluralize}Controller"
|
122
|
+
end
|
123
|
+
|
124
|
+
private def defaults
|
125
|
+
route.defaults
|
126
|
+
end
|
127
|
+
|
128
|
+
private def configuration
|
129
|
+
controller.instance_variable_get(:@jsonapi_home_endpoint)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module JSONAPI
|
2
|
+
module Home
|
3
|
+
module V1
|
4
|
+
class ResourceRealizer
|
5
|
+
include JSONAPI::Realizer::Resource
|
6
|
+
|
7
|
+
register :jsonapi_home_resources, class_name: "JSONAPI::Home::V1::Resource", adapter: :memory
|
8
|
+
|
9
|
+
has :namespace
|
10
|
+
has :version
|
11
|
+
has :intent
|
12
|
+
has :verb
|
13
|
+
has :href
|
14
|
+
has :deprecated
|
15
|
+
has :mediatype
|
16
|
+
has :description
|
17
|
+
has :created_at
|
18
|
+
has :updated_at
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module JSONAPI
|
2
|
+
module Home
|
3
|
+
module V1
|
4
|
+
class ResourceSerializer
|
5
|
+
include JSONAPI::Serializer
|
6
|
+
|
7
|
+
attribute :namespace
|
8
|
+
attribute :version
|
9
|
+
attribute :intent
|
10
|
+
attribute :description
|
11
|
+
attribute :deprecated
|
12
|
+
attribute :verb
|
13
|
+
attribute :href
|
14
|
+
attribute :mediatype
|
15
|
+
attribute :created_at
|
16
|
+
attribute :updated_at
|
17
|
+
|
18
|
+
def type
|
19
|
+
"jsonapi-home-resources"
|
20
|
+
end
|
21
|
+
|
22
|
+
def jsonapi
|
23
|
+
{
|
24
|
+
version: object.jsonapi_version
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def meta
|
29
|
+
[
|
30
|
+
if object.documentation
|
31
|
+
{
|
32
|
+
documentation: {
|
33
|
+
href: object.documentation
|
34
|
+
}
|
35
|
+
}
|
36
|
+
end,
|
37
|
+
].compact.reduce(&:merge)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
JSONAPI::Home::Engine.routes.draw do
|
2
|
+
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
|
3
|
+
|
4
|
+
namespace :v1 do
|
5
|
+
resources :jsonapi_home_resources, controller: :resources, path: "jsonapi-home-resources", only: [:index, :show]
|
6
|
+
end
|
7
|
+
end
|
data/lib/jsonapi-home.rb
ADDED
data/lib/jsonapi/home.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "jsonapi-realizer"
|
2
|
+
require "jsonapi-serializers"
|
3
|
+
require "array-where"
|
4
|
+
|
5
|
+
module JSONAPI
|
6
|
+
MEDIA_TYPE = "application/vnd.api+json" unless const_defined?("MEDIA_TYPE")
|
7
|
+
|
8
|
+
module Home
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
DEFAULT_DESCRIPTION = "A JSON:API resource as defined at https://www.jsonapi.org"
|
12
|
+
|
13
|
+
require_relative "home/inflector"
|
14
|
+
require_relative "home/engine"
|
15
|
+
|
16
|
+
class_methods do
|
17
|
+
def discoverable(version:, namespace:, deprecated: nil, description: DEFAULT_DESCRIPTION, documentation: nil, location: nil, jsonapi_version: "1.0")
|
18
|
+
instance_variable_set(:@jsonapi_home_endpoint, {
|
19
|
+
location: location,
|
20
|
+
description: description,
|
21
|
+
deprecated: deprecated,
|
22
|
+
documentation: documentation,
|
23
|
+
jsonapi_version: jsonapi_version,
|
24
|
+
version: version,
|
25
|
+
namespace: namespace
|
26
|
+
})
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jsonapi-home
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kurtis Rainbolt-Greene
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-03-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.16.1
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.16.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.7.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.7.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 12.3.1
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 12.3.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.11.3
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.11.3
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry-doc
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.13.3
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.13.3
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: sqlite3
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.3.13
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.3.13
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rails
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 5.1.5
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 5.1.5
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: jsonapi-realizer
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 4.1.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 4.1.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: jsonapi-serializers
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 1.0.0
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 1.0.0
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: array-where
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - '='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 2.0.0
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - '='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 2.0.0
|
153
|
+
description: An early implementation of JSONAPIHome, a fork of JSONHome
|
154
|
+
email:
|
155
|
+
- kurtis@rainbolt-greene.online
|
156
|
+
executables: []
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files: []
|
159
|
+
files:
|
160
|
+
- README.md
|
161
|
+
- Rakefile
|
162
|
+
- app/controllers/jsonapi/home/v1/resources_controller.rb
|
163
|
+
- app/models/jsonapi/home/v1/resource.rb
|
164
|
+
- app/realizers/jsonapi/home/v1/resource_realizer.rb
|
165
|
+
- app/serializers/jsonapi/home/v1/resource_serializer.rb
|
166
|
+
- config/routes.rb
|
167
|
+
- lib/jsonapi-home.rb
|
168
|
+
- lib/jsonapi/home.rb
|
169
|
+
- lib/jsonapi/home/engine.rb
|
170
|
+
- lib/jsonapi/home/inflector.rb
|
171
|
+
- lib/jsonapi/home/version.rb
|
172
|
+
- lib/jsonapi/home_spec.rb
|
173
|
+
homepage: http://krainboltgreene.github.io/jsonapi-home
|
174
|
+
licenses:
|
175
|
+
- ISC
|
176
|
+
metadata: {}
|
177
|
+
post_install_message:
|
178
|
+
rdoc_options: []
|
179
|
+
require_paths:
|
180
|
+
- lib
|
181
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
182
|
+
requirements:
|
183
|
+
- - ">="
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '0'
|
186
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
|
+
requirements:
|
188
|
+
- - ">="
|
189
|
+
- !ruby/object:Gem::Version
|
190
|
+
version: '0'
|
191
|
+
requirements: []
|
192
|
+
rubyforge_project:
|
193
|
+
rubygems_version: 2.7.6
|
194
|
+
signing_key:
|
195
|
+
specification_version: 4
|
196
|
+
summary: An early implementation of JSONAPIHome, a fork of JSONHome
|
197
|
+
test_files: []
|