jsonapi-utils 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +556 -16
- data/jsonapi-utils.gemspec +2 -2
- data/lib/jsonapi/utils.rb +1 -1
- data/lib/jsonapi/utils/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7dd1257dc06616941f1a935884e1b3e18ced4898
|
4
|
+
data.tar.gz: e464f7c33b4c462e6a9ddc94d669f0b1558a6b6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 231eff83798cb798e4c3e3e28821acea750b82b9b0c51a479678bc9523d7ff815bb8e1151272ace7a7da9abb445751e49450fc0b7f0386efa00f97f98090b56c
|
7
|
+
data.tar.gz: 7a5a0d73d18304b431e61788769cf603411c01da961de76865d1499b1f6e4974934ba5eb7fe0e0e397b2dc17e0175b4f55cb72a3cefe31f36f13a0e1b621a021
|
data/README.md
CHANGED
@@ -1,36 +1,576 @@
|
|
1
1
|
# JSONAPI::Utils
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
* Describe something about the awesome `jsonapi-resources` gem
|
8
|
-
* Describe how it's easy to serialize JSON API-based responses using the `jsonapi-utils` gem
|
9
|
-
* JSONAPI::Utils#jsonapi_render (show options like `json`, `resource`, `model`, `scope` and `count`)
|
10
|
-
* JSONAPI::Utils#jsonapi_serialize
|
11
|
-
* Example of a model
|
12
|
-
* Example of a resource
|
13
|
-
* Example of a base controller and another whatever controller
|
3
|
+
JSON::Utils is a simple way to get a full-featured [JSON API](jsonapi.org) serialization in your
|
4
|
+
controller's responses. This gem works on top of the awesome gem [jsonapi-resources](https://github.com/cerebris/jsonapi-resources),
|
5
|
+
bringing to controllers a Rails-native way to render data.
|
14
6
|
|
15
7
|
## Installation
|
16
8
|
|
17
|
-
Add
|
9
|
+
Add these lines to your application's Gemfile:
|
18
10
|
|
19
11
|
```ruby
|
12
|
+
gem 'jsonapi-resources', '~> 0.5.7'
|
20
13
|
gem 'jsonapi-utils'
|
21
14
|
```
|
22
15
|
|
23
16
|
And then execute:
|
24
17
|
|
25
|
-
|
18
|
+
```shell
|
19
|
+
$ bundle
|
20
|
+
```
|
21
|
+
|
22
|
+
## Macros
|
23
|
+
|
24
|
+
* `jsonapi_render`: it works like ActionController's `render` method, receiving model objects and
|
25
|
+
rendering them into JSON API's data format.
|
26
|
+
|
27
|
+
* `jsonapi_serialize`: in the backstage, it's the method that actually parsers model objects or hashes and builds JSON data.
|
28
|
+
It can be called anywhere in controllers, concerns etc.
|
29
|
+
|
30
|
+
## Options
|
31
|
+
|
32
|
+
Those macros accept the following options:
|
33
|
+
|
34
|
+
* `resource`: explicitly points the resource to be used in the serialization. By default, JSONAPI::Utils will
|
35
|
+
select resources by inferencing from controller's name.
|
26
36
|
|
27
|
-
|
37
|
+
```ruby
|
38
|
+
# If in UsersController for some reason it needs to render a different resource:
|
39
|
+
jsonapi_render json: Post.all, options: { resource: PostResource }
|
40
|
+
```
|
41
|
+
|
42
|
+
* `count`: explicitly points the total count of records for the request, in order to build a proper pagination. By default, JSONAPI::Utils will
|
43
|
+
count the total number of records for a given resource.
|
28
44
|
|
29
|
-
|
45
|
+
```ruby
|
46
|
+
users = User.all
|
47
|
+
jsonapi_render json: users, options: { count: users.size }
|
48
|
+
```
|
30
49
|
|
31
50
|
## Usage
|
32
51
|
|
33
|
-
|
52
|
+
Let's say we have a Rails app for a super simple blog.
|
53
|
+
|
54
|
+
### Models
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
# app/models/user.rb
|
58
|
+
class User < ActiveRecord::Base
|
59
|
+
has_many :posts
|
60
|
+
validates :first_name, :last_name, presence: true
|
61
|
+
end
|
62
|
+
|
63
|
+
# app/models/user.rb
|
64
|
+
class Post < ActiveRecord::Base
|
65
|
+
belongs_to :author, class_name: 'User', foreign_key: 'user_id'
|
66
|
+
validates :title, :body, presence: true
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
### Resources
|
71
|
+
|
72
|
+
Here is where we define how the serialization will behave:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
# app/resources/user_resource.rb
|
76
|
+
class UserResource < JSONAPI::Resource
|
77
|
+
attributes :first_name, :last_name, :full_name, :birthday
|
78
|
+
attribute :full_name
|
79
|
+
|
80
|
+
has_many :posts
|
81
|
+
|
82
|
+
def full_name
|
83
|
+
"#{@model.first_name} #{@model.last_name}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# app/resources/post_resource.rb
|
88
|
+
class PostResource < JSONAPI::Resource
|
89
|
+
attributes :title, :body
|
90
|
+
has_one :author
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
### Routes & Controllers
|
95
|
+
|
96
|
+
Let's define our routes using the `jsonapi_resources` and `jsonapi_links` macros provied by the `jsonapi-resources` gem:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
Rails.application.routes.draw do
|
100
|
+
jsonapi_resources :users do
|
101
|
+
jsonapi_resources :posts
|
102
|
+
jsonapi_links :posts
|
103
|
+
end
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
And a base controller to include the features from `jsonapi-resources` and `jsonapi-utils`:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
# app/controllers/base_controller.rb
|
111
|
+
class BaseController < JSONAPI::ResourceController
|
112
|
+
include JSONAPI::Utils
|
113
|
+
protect_from_forgery with: :null_session
|
114
|
+
rescue_from ActiveRecord::RecordNotFound, with: :jsonapi_render_not_found
|
115
|
+
end
|
116
|
+
```
|
117
|
+
|
118
|
+
For this example, let's get focused only on read actions. After including `JSONAPI::Utils` we can use the `jsonapi_render` method
|
119
|
+
in order to generate responses which follow the JSON API's standards.
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
# app/controllers/users_controller.rb
|
123
|
+
class UsersController < BaseController
|
124
|
+
before_action :load_user, only: [:show]
|
125
|
+
|
126
|
+
# GET /users
|
127
|
+
def index
|
128
|
+
users = User.all
|
129
|
+
jsonapi_render json: users, options: { count: users.size }
|
130
|
+
end
|
131
|
+
|
132
|
+
# GET /users/:id
|
133
|
+
def show
|
134
|
+
jsonapi_render json: @user
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
def load_user
|
140
|
+
@user = User.find(params[:id])
|
141
|
+
end
|
142
|
+
end
|
143
|
+
```
|
144
|
+
|
145
|
+
And:
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
# app/controllers/posts_controller.rb
|
149
|
+
class PostsController < BaseController
|
150
|
+
before_action :load_user, only: [:index, :show]
|
151
|
+
before_action :load_post, only: [:show]
|
152
|
+
|
153
|
+
# GET /users/:user_id/posts
|
154
|
+
def index
|
155
|
+
jsonapi_render json: @user.posts, options: { count: @user.posts.size }
|
156
|
+
end
|
157
|
+
|
158
|
+
# GET /users/:user_id/posts/:id
|
159
|
+
def show
|
160
|
+
jsonapi_render json: @post
|
161
|
+
end
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
def load_user
|
166
|
+
@user = User.find(params[:user_id])
|
167
|
+
end
|
168
|
+
|
169
|
+
def load_post
|
170
|
+
@post = @user.posts.find(params[:id])
|
171
|
+
end
|
172
|
+
end
|
173
|
+
```
|
174
|
+
|
175
|
+
### Erros
|
176
|
+
|
177
|
+
#### Not found
|
178
|
+
|
179
|
+
As you might have seen in BaseController this line will handle all errors related to not found resources:
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
rescue_from ActiveRecord::RecordNotFound, with: :jsonapi_render_not_found
|
183
|
+
```
|
184
|
+
|
185
|
+
The `jsonapi_render_not_found` method will produce the following error payload:
|
186
|
+
|
187
|
+
```json
|
188
|
+
HTTP/1.1 404 Not found
|
189
|
+
Content-Type: application/vnd.api+json
|
190
|
+
|
191
|
+
{
|
192
|
+
"errors": [
|
193
|
+
{
|
194
|
+
"title": "Record not found",
|
195
|
+
"detail": "The record identified by 3 could not be found.",
|
196
|
+
"id": null,
|
197
|
+
"href": null,
|
198
|
+
"code": 404,
|
199
|
+
"source": null,
|
200
|
+
"links": null,
|
201
|
+
"status": "not_found"
|
202
|
+
}
|
203
|
+
]
|
204
|
+
}
|
205
|
+
```
|
206
|
+
|
207
|
+
In case you prefer rendering not found resources with null data and `200 OK` status code, you can use `jsonapi_render_not_found_with_null` to produce:
|
208
|
+
|
209
|
+
```json
|
210
|
+
HTTP/1.1 200 OK
|
211
|
+
Content-Type: application/vnd.api+json
|
212
|
+
|
213
|
+
{
|
214
|
+
"data": null
|
215
|
+
}
|
216
|
+
```
|
217
|
+
|
218
|
+
If you need to create custom error message, check [this](https://github.com/cerebris/jsonapi-resources#error-codes).
|
219
|
+
|
220
|
+
### Initializer
|
221
|
+
|
222
|
+
In order to enable a proper pagination, record count etc, let's define an initializer such as:
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
# config/initializers/jsonapi_resources.rb
|
226
|
+
JSONAPI.configure do |config|
|
227
|
+
config.json_key_format = :underscored_key
|
228
|
+
config.route_format = :dasherized_route
|
229
|
+
|
230
|
+
config.operations_processor = :active_record
|
231
|
+
|
232
|
+
config.allow_include = true
|
233
|
+
config.allow_sort = true
|
234
|
+
config.allow_filter = true
|
235
|
+
|
236
|
+
config.raise_if_parameters_not_allowed = true
|
237
|
+
|
238
|
+
config.default_paginator = :paged
|
239
|
+
|
240
|
+
config.top_level_links_include_pagination = true
|
241
|
+
|
242
|
+
config.default_page_size = 10
|
243
|
+
config.maximum_page_size = 20
|
244
|
+
|
245
|
+
config.top_level_meta_include_record_count = true
|
246
|
+
config.top_level_meta_record_count_key = :record_count
|
247
|
+
|
248
|
+
config.use_text_errors = false
|
249
|
+
|
250
|
+
config.exception_class_whitelist = []
|
251
|
+
|
252
|
+
config.always_include_to_one_linkage_data = false
|
253
|
+
end
|
254
|
+
```
|
255
|
+
|
256
|
+
You may want a different configuration for your API. For more information check [this](https://github.com/cerebris/jsonapi-resources/#configuration).
|
257
|
+
|
258
|
+
### Requests & Responses
|
259
|
+
|
260
|
+
Here's some examples of requests – based on those sample [controllers](#routes--controllers) – and their respective JSON responses.
|
261
|
+
|
262
|
+
* [Collection](#collection)
|
263
|
+
* [Collection (options)](#collection-options)
|
264
|
+
* [Single record](#single-record)
|
265
|
+
* [Record (options)](#single-record-options)
|
266
|
+
* [Relationships (identifier objects)](#relationships-identifier-objects)
|
267
|
+
* [Nested resources](#nested-resources)
|
268
|
+
|
269
|
+
#### Collection
|
270
|
+
|
271
|
+
Request:
|
272
|
+
|
273
|
+
```
|
274
|
+
GET /users HTTP/1.1
|
275
|
+
Accept: application/vnd.api+json
|
276
|
+
```
|
277
|
+
|
278
|
+
Response:
|
279
|
+
|
280
|
+
```json
|
281
|
+
HTTP/1.1 200 OK
|
282
|
+
Content-Type: application/vnd.api+json
|
283
|
+
|
284
|
+
{
|
285
|
+
"data": [
|
286
|
+
{
|
287
|
+
"id": "1",
|
288
|
+
"type": "users",
|
289
|
+
"links": {
|
290
|
+
"self": "http://api.myblog.com/users/1"
|
291
|
+
},
|
292
|
+
"attributes": {
|
293
|
+
"first_name": "Tiago",
|
294
|
+
"last_name": "Guedes",
|
295
|
+
"full_name": "Tiago Guedes",
|
296
|
+
"birthday": null
|
297
|
+
},
|
298
|
+
"relationships": {
|
299
|
+
"posts": {
|
300
|
+
"links": {
|
301
|
+
"self": "http://api.myblog.com/users/1/relationships/posts",
|
302
|
+
"related": "http://api.myblog.com/users/1/posts"
|
303
|
+
}
|
304
|
+
}
|
305
|
+
}
|
306
|
+
},
|
307
|
+
{
|
308
|
+
"id": "2",
|
309
|
+
"type": "users",
|
310
|
+
"links": {
|
311
|
+
"self": "http://api.myblog.com/users/2"
|
312
|
+
},
|
313
|
+
"attributes": {
|
314
|
+
"first_name": "Douglas",
|
315
|
+
"last_name": "André",
|
316
|
+
"full_name": "Douglas André",
|
317
|
+
"birthday": null
|
318
|
+
},
|
319
|
+
"relationships": {
|
320
|
+
"posts": {
|
321
|
+
"links": {
|
322
|
+
"self": "http://api.myblog.com/users/2/relationships/posts",
|
323
|
+
"related": "http://api.myblog.com/users/2/posts"
|
324
|
+
}
|
325
|
+
}
|
326
|
+
}
|
327
|
+
}
|
328
|
+
],
|
329
|
+
"meta": {
|
330
|
+
"record_count": 2
|
331
|
+
},
|
332
|
+
"links": {
|
333
|
+
"first": "http://api.myblog.com/users?page%5Bnumber%5D=1&page%5Bsize%5D=10",
|
334
|
+
"last": "http://api.myblog.com/users?page%5Bnumber%5D=1&page%5Bsize%5D=10"
|
335
|
+
}
|
336
|
+
}
|
337
|
+
```
|
338
|
+
|
339
|
+
#### Collection (options)
|
340
|
+
|
341
|
+
Request:
|
342
|
+
|
343
|
+
```
|
344
|
+
GET /users?include=posts&fields[users]=full_name,posts&fields[posts]=title&page[number]=1&page[size]=1 HTTP/1.1
|
345
|
+
Accept: application/vnd.api+json
|
346
|
+
```
|
347
|
+
|
348
|
+
Response:
|
349
|
+
|
350
|
+
```json
|
351
|
+
HTTP/1.1 200 OK
|
352
|
+
Content-Type: application/vnd.api+json
|
353
|
+
|
354
|
+
{
|
355
|
+
"data": [
|
356
|
+
{
|
357
|
+
"id": "1",
|
358
|
+
"type": "users",
|
359
|
+
"links": {
|
360
|
+
"self": "http://api.myblog.com/users/1"
|
361
|
+
},
|
362
|
+
"attributes": {
|
363
|
+
"full_name": "Tiago Guedes"
|
364
|
+
},
|
365
|
+
"relationships": {
|
366
|
+
"posts": {
|
367
|
+
"links": {
|
368
|
+
"self": "http://api.myblog.com/users/1/relationships/posts",
|
369
|
+
"related": "http://api.myblog.com/users/1/posts"
|
370
|
+
},
|
371
|
+
"data": [
|
372
|
+
{
|
373
|
+
"type": "posts",
|
374
|
+
"id": "1"
|
375
|
+
}
|
376
|
+
]
|
377
|
+
}
|
378
|
+
}
|
379
|
+
}
|
380
|
+
],
|
381
|
+
"included": [
|
382
|
+
{
|
383
|
+
"id": "1",
|
384
|
+
"type": "posts",
|
385
|
+
"links": {
|
386
|
+
"self": "http://api.myblog.com/posts/1"
|
387
|
+
},
|
388
|
+
"attributes": {
|
389
|
+
"title": "An awesome post"
|
390
|
+
}
|
391
|
+
}
|
392
|
+
],
|
393
|
+
"meta": {
|
394
|
+
"record_count": 2
|
395
|
+
},
|
396
|
+
"links": {
|
397
|
+
"first": "http://api.myblog.com/users?fields%5Bposts%5D=title&fields%5Busers%5D=full_name%2Cposts&include=posts&page%5Bnumber%5D=1&page%5Bsize%5D=1",
|
398
|
+
"next": "http://api.myblog.com/users?fields%5Bposts%5D=title&fields%5Busers%5D=full_name%2Cposts&include=posts&page%5Bnumber%5D=2&page%5Bsize%5D=1",
|
399
|
+
"last": "http://api.myblog.com/users?fields%5Bposts%5D=title&fields%5Busers%5D=full_name%2Cposts&include=posts&page%5Bnumber%5D=2&page%5Bsize%5D=1"
|
400
|
+
}
|
401
|
+
}
|
402
|
+
```
|
403
|
+
|
404
|
+
#### Single record
|
405
|
+
|
406
|
+
Request:
|
407
|
+
|
408
|
+
```
|
409
|
+
GET /users/1 HTTP/1.1
|
410
|
+
Accept: application/vnd.api+json
|
411
|
+
```
|
412
|
+
|
413
|
+
Response:
|
414
|
+
|
415
|
+
```json
|
416
|
+
HTTP/1.1 200 OK
|
417
|
+
Content-Type: application/vnd.api+json
|
418
|
+
|
419
|
+
{
|
420
|
+
"data": {
|
421
|
+
"id": "1",
|
422
|
+
"type": "users",
|
423
|
+
"links": {
|
424
|
+
"self": "http://api.myblog.com/users/1"
|
425
|
+
},
|
426
|
+
"attributes": {
|
427
|
+
"first_name": "Tiago",
|
428
|
+
"last_name": "Guedes",
|
429
|
+
"full_name": "Tiago Guedes",
|
430
|
+
"birthday": null
|
431
|
+
},
|
432
|
+
"relationships": {
|
433
|
+
"posts": {
|
434
|
+
"links": {
|
435
|
+
"self": "http://api.myblog.com/users/1/relationships/posts",
|
436
|
+
"related": "http://api.myblog.com/users/1/posts"
|
437
|
+
}
|
438
|
+
}
|
439
|
+
}
|
440
|
+
}
|
441
|
+
}
|
442
|
+
```
|
443
|
+
|
444
|
+
#### Single record (options)
|
445
|
+
|
446
|
+
Request:
|
447
|
+
|
448
|
+
```
|
449
|
+
GET /users/1?include=posts&fields[users]=full_name,posts&fields[posts]=title HTTP/1.1
|
450
|
+
Accept: application/vnd.api+json
|
451
|
+
```
|
452
|
+
|
453
|
+
Response:
|
454
|
+
|
455
|
+
```json
|
456
|
+
HTTP/1.1 200 OK
|
457
|
+
Content-Type: application/vnd.api+json
|
458
|
+
|
459
|
+
{
|
460
|
+
"data": {
|
461
|
+
"id": "1",
|
462
|
+
"type": "users",
|
463
|
+
"links": {
|
464
|
+
"self": "http://api.myblog.com/users/1"
|
465
|
+
},
|
466
|
+
"attributes": {
|
467
|
+
"full_name": "Tiago Guedes"
|
468
|
+
},
|
469
|
+
"relationships": {
|
470
|
+
"posts": {
|
471
|
+
"links": {
|
472
|
+
"self": "http://api.myblog.com/users/1/relationships/posts",
|
473
|
+
"related": "http://api.myblog.com/users/1/posts"
|
474
|
+
},
|
475
|
+
"data": [
|
476
|
+
{
|
477
|
+
"type": "posts",
|
478
|
+
"id": "1"
|
479
|
+
}
|
480
|
+
]
|
481
|
+
}
|
482
|
+
}
|
483
|
+
},
|
484
|
+
"included": [
|
485
|
+
{
|
486
|
+
"id": "1",
|
487
|
+
"type": "posts",
|
488
|
+
"links": {
|
489
|
+
"self": "http://api.myblog.com/posts/1"
|
490
|
+
},
|
491
|
+
"attributes": {
|
492
|
+
"title": "An awesome post"
|
493
|
+
}
|
494
|
+
}
|
495
|
+
]
|
496
|
+
}
|
497
|
+
```
|
498
|
+
|
499
|
+
#### Relationships (identifier objects)
|
500
|
+
|
501
|
+
Request:
|
502
|
+
|
503
|
+
```
|
504
|
+
GET /users/1/relationships/posts HTTP/1.1
|
505
|
+
Accept: application/vnd.api+json
|
506
|
+
```
|
507
|
+
|
508
|
+
Response:
|
509
|
+
|
510
|
+
```json
|
511
|
+
HTTP/1.1 200 OK
|
512
|
+
Content-Type: application/vnd.api+json
|
513
|
+
|
514
|
+
{
|
515
|
+
"links": {
|
516
|
+
"self": "http://api.myblog.com/users/1/relationships/posts",
|
517
|
+
"related": "http://api.myblog.com/users/1/posts"
|
518
|
+
},
|
519
|
+
"data": [
|
520
|
+
{
|
521
|
+
"type": "posts",
|
522
|
+
"id": "1"
|
523
|
+
}
|
524
|
+
]
|
525
|
+
}
|
526
|
+
```
|
527
|
+
|
528
|
+
#### Nested resources
|
529
|
+
|
530
|
+
Request:
|
531
|
+
|
532
|
+
```
|
533
|
+
GET /users/1/posts HTTP/1.1
|
534
|
+
Accept: application/vnd.api+json
|
535
|
+
```
|
536
|
+
|
537
|
+
Response:
|
538
|
+
|
539
|
+
```json
|
540
|
+
HTTP/1.1 200 OK
|
541
|
+
Content-Type: application/vnd.api+json
|
542
|
+
|
543
|
+
{
|
544
|
+
"data": [
|
545
|
+
{
|
546
|
+
"id": "1",
|
547
|
+
"type": "posts",
|
548
|
+
"links": {
|
549
|
+
"self": "http://api.myblog.com/posts/1"
|
550
|
+
},
|
551
|
+
"attributes": {
|
552
|
+
"title": "An awesome post",
|
553
|
+
"body": "Lorem ipsum dolot sit amet"
|
554
|
+
},
|
555
|
+
"relationships": {
|
556
|
+
"author": {
|
557
|
+
"links": {
|
558
|
+
"self": "http://api.myblog.com/posts/1/relationships/author",
|
559
|
+
"related": "http://api.myblog.com/posts/1/author"
|
560
|
+
}
|
561
|
+
}
|
562
|
+
}
|
563
|
+
}
|
564
|
+
],
|
565
|
+
"meta": {
|
566
|
+
"record_count": 1
|
567
|
+
},
|
568
|
+
"links": {
|
569
|
+
"first": "http://api.myblog.com/posts?page%5Bnumber%5D=1&page%5Bsize%5D=10",
|
570
|
+
"last": "http://api.myblog.com/posts?page%5Bnumber%5D=1&page%5Bsize%5D=10"
|
571
|
+
}
|
572
|
+
}
|
573
|
+
```
|
34
574
|
|
35
575
|
## Development
|
36
576
|
|
data/jsonapi-utils.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Tiago Guedes", "Douglas André"]
|
10
10
|
spec.email = ["tiagopog@gmail.com", "douglas@beautydate.com.br"]
|
11
11
|
|
12
|
-
spec.summary = %q{
|
13
|
-
spec.description = %q{A Rails
|
12
|
+
spec.summary = %q{JSON::Utils is a simple way to get a full-featured JSON API serialization for your controller's responses.}
|
13
|
+
spec.description = %q{A Rails way to get your API's data following the JSON API's specs (http://jsosapi.org)}
|
14
14
|
spec.homepage = "https://github.com/b2beauty/jsonapi-utils"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
data/lib/jsonapi/utils.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi-utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tiago Guedes
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-09-
|
12
|
+
date: 2015-09-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -53,8 +53,7 @@ dependencies:
|
|
53
53
|
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '0'
|
56
|
-
description: A Rails
|
57
|
-
specs (http://jsosapi.org)
|
56
|
+
description: A Rails way to get your API's data following the JSON API's specs (http://jsosapi.org)
|
58
57
|
email:
|
59
58
|
- tiagopog@gmail.com
|
60
59
|
- douglas@beautydate.com.br
|
@@ -95,8 +94,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
94
|
version: '0'
|
96
95
|
requirements: []
|
97
96
|
rubyforge_project:
|
98
|
-
rubygems_version: 2.4.
|
97
|
+
rubygems_version: 2.4.5.1
|
99
98
|
signing_key:
|
100
99
|
specification_version: 4
|
101
|
-
summary:
|
100
|
+
summary: JSON::Utils is a simple way to get a full-featured JSON API serialization
|
101
|
+
for your controller's responses.
|
102
102
|
test_files: []
|