jsonapi-home 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
- [![Build](http://img.shields.io/travis-ci/krainboltgreene/jsonapi-home.svg?style=flat-square)](https://travis-ci.org/krainboltgreene/jsonapi-home)
|
4
|
+
- [![Downloads](http://img.shields.io/gem/dtv/jsonapi-home.svg?style=flat-square)](https://rubygems.org/gems/jsonapi-home)
|
5
|
+
- [![Version](http://img.shields.io/gem/v/jsonapi-home.svg?style=flat-square)](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: []
|