jsonapi-serializers 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +48 -1
- data/lib/jsonapi-serializers/attributes.rb +4 -0
- data/lib/jsonapi-serializers/serializer.rb +18 -12
- data/lib/jsonapi-serializers/version.rb +1 -1
- data/spec/serializer_spec.rb +66 -0
- data/spec/support/serializers.rb +26 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b670315a342425c1d55f313aa4bc0830e1b0a69e
|
4
|
+
data.tar.gz: d2be33728c559adbee37316b70087369d5513389
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70dc34dd00b999e5805012212e80daa22510a2665b77366e657c6e809a7812ca143af7db8789fb88fe9a590f5c343bd25a164fee1903da79f74df0d52fb186d6
|
7
|
+
data.tar.gz: e254988e99b57b4108c7cecf35e065751b164722dc751fb14bdf46818f8922a3162c7780b3479625450a21d41872005411c6fbe2a6bfa56c6778a41a5f926ae0
|
data/README.md
CHANGED
@@ -24,6 +24,7 @@ This library is up-to-date with the finalized v1 JSON API spec.
|
|
24
24
|
* [Relationships](#relationships)
|
25
25
|
* [Compound documents and includes](#compound-documents-and-includes)
|
26
26
|
* [Relationship path handling](#relationship-path-handling)
|
27
|
+
* [Control links and data in relationships](#control-links-and-data-in-relationships)
|
27
28
|
* [Rails example](#rails-example)
|
28
29
|
* [Sinatra example](#sinatra-example)
|
29
30
|
* [Unfinished business](#unfinished-business)
|
@@ -333,7 +334,7 @@ JSONAPI::Serializer.serialize_errors(user.errors)
|
|
333
334
|
|
334
335
|
A more complete usage example (assumes ActiveModel):
|
335
336
|
|
336
|
-
```
|
337
|
+
```ruby
|
337
338
|
class Api::V1::ReposController < Api::V1::BaseController
|
338
339
|
def create
|
339
340
|
post = Post.create(post_params)
|
@@ -509,6 +510,52 @@ Notice a few things:
|
|
509
510
|
|
510
511
|
The `include` param also accepts a string of [relationship paths](http://jsonapi.org/format/#fetching-includes), ie. `include: 'author,comments,comments.user'` so you can pass an `?include` query param directly through to the serialize method. Be aware that letting users pass arbitrary relationship paths might introduce security issues depending on your authorization setup, where a user could `include` a relationship they might not be authorized to see directly. Be aware of what you allow API users to include.
|
511
512
|
|
513
|
+
### Control `links` and `data` in relationships
|
514
|
+
|
515
|
+
The JSON API spec allows relationships objects to contain `links`, `data`, or both.
|
516
|
+
|
517
|
+
By default, `links` are included in each relationship. You can remove links for a specific relationship by passing `include_links: false` to `has_one` or `has_many`. For example:
|
518
|
+
|
519
|
+
```ruby
|
520
|
+
has_many :comments, include_links: false # Default is include_links: true.
|
521
|
+
```
|
522
|
+
|
523
|
+
Notice that `links` are now excluded for the `comments` relationship:
|
524
|
+
|
525
|
+
```json
|
526
|
+
"relationships": {
|
527
|
+
"author": {
|
528
|
+
"links": {
|
529
|
+
"self": "/posts/1/relationships/author",
|
530
|
+
"related": "/posts/1/author"
|
531
|
+
}
|
532
|
+
},
|
533
|
+
"comments": {}
|
534
|
+
}
|
535
|
+
```
|
536
|
+
|
537
|
+
By default, `data` is excluded in each relationship. You can enable data for a specific relationship by passing `include_data: true` to `has_one` or `has_many`. For example:
|
538
|
+
|
539
|
+
```ruby
|
540
|
+
has_one :author, include_data: true # Default is include_data: false.
|
541
|
+
```
|
542
|
+
|
543
|
+
Notice that linkage data is now included for the `author` relationship:
|
544
|
+
|
545
|
+
```json
|
546
|
+
"relationships": {
|
547
|
+
"author": {
|
548
|
+
"links": {
|
549
|
+
"self": "/posts/1/relationships/author",
|
550
|
+
"related": "/posts/1/author"
|
551
|
+
},
|
552
|
+
"data": {
|
553
|
+
"type": "users",
|
554
|
+
"id": "1"
|
555
|
+
}
|
556
|
+
}
|
557
|
+
```
|
558
|
+
|
512
559
|
## Rails example
|
513
560
|
|
514
561
|
```ruby
|
@@ -52,6 +52,8 @@ module JSONAPI
|
|
52
52
|
private :add_attribute
|
53
53
|
|
54
54
|
def add_to_one_association(name, options = {}, &block)
|
55
|
+
options[:include_links] = options.fetch(:include_links, true)
|
56
|
+
options[:include_data] = options.fetch(:include_data, false)
|
55
57
|
@to_one_associations ||= {}
|
56
58
|
@to_one_associations[name] = {
|
57
59
|
attr_or_block: block_given? ? block : name,
|
@@ -61,6 +63,8 @@ module JSONAPI
|
|
61
63
|
private :add_to_one_association
|
62
64
|
|
63
65
|
def add_to_many_association(name, options = {}, &block)
|
66
|
+
options[:include_links] = options.fetch(:include_links, true)
|
67
|
+
options[:include_data] = options.fetch(:include_data, false)
|
64
68
|
@to_many_associations ||= {}
|
65
69
|
@to_many_associations[name] = {
|
66
70
|
attr_or_block: block_given? ? block : name,
|
@@ -97,13 +97,16 @@ module JSONAPI
|
|
97
97
|
formatted_attribute_name = format_name(attribute_name)
|
98
98
|
|
99
99
|
data[formatted_attribute_name] = {}
|
100
|
-
links_self = relationship_self_link(attribute_name)
|
101
|
-
links_related = relationship_related_link(attribute_name)
|
102
|
-
data[formatted_attribute_name]['links'] = {} if links_self || links_related
|
103
|
-
data[formatted_attribute_name]['links']['self'] = links_self if links_self
|
104
|
-
data[formatted_attribute_name]['links']['related'] = links_related if links_related
|
105
100
|
|
106
|
-
if
|
101
|
+
if attr_data[:options][:include_links]
|
102
|
+
links_self = relationship_self_link(attribute_name)
|
103
|
+
links_related = relationship_related_link(attribute_name)
|
104
|
+
data[formatted_attribute_name]['links'] = {} if links_self || links_related
|
105
|
+
data[formatted_attribute_name]['links']['self'] = links_self if links_self
|
106
|
+
data[formatted_attribute_name]['links']['related'] = links_related if links_related
|
107
|
+
end
|
108
|
+
|
109
|
+
if @_include_linkages.include?(formatted_attribute_name) || attr_data[:options][:include_data]
|
107
110
|
object = has_one_relationship(attribute_name, attr_data)
|
108
111
|
if object.nil?
|
109
112
|
# Spec: Resource linkage MUST be represented as one of the following:
|
@@ -125,17 +128,20 @@ module JSONAPI
|
|
125
128
|
formatted_attribute_name = format_name(attribute_name)
|
126
129
|
|
127
130
|
data[formatted_attribute_name] = {}
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
131
|
+
|
132
|
+
if attr_data[:options][:include_links]
|
133
|
+
links_self = relationship_self_link(attribute_name)
|
134
|
+
links_related = relationship_related_link(attribute_name)
|
135
|
+
data[formatted_attribute_name]['links'] = {} if links_self || links_related
|
136
|
+
data[formatted_attribute_name]['links']['self'] = links_self if links_self
|
137
|
+
data[formatted_attribute_name]['links']['related'] = links_related if links_related
|
138
|
+
end
|
133
139
|
|
134
140
|
# Spec: Resource linkage MUST be represented as one of the following:
|
135
141
|
# - an empty array ([]) for empty to-many relationships.
|
136
142
|
# - an array of linkage objects for non-empty to-many relationships.
|
137
143
|
# http://jsonapi.org/format/#document-structure-resource-relationships
|
138
|
-
if @_include_linkages.include?(formatted_attribute_name)
|
144
|
+
if @_include_linkages.include?(formatted_attribute_name) || attr_data[:options][:include_data]
|
139
145
|
data[formatted_attribute_name]['data'] = []
|
140
146
|
objects = has_many_relationship(attribute_name, attr_data) || []
|
141
147
|
objects.each do |obj|
|
data/spec/serializer_spec.rb
CHANGED
@@ -352,6 +352,72 @@ describe JSONAPI::Serializer do
|
|
352
352
|
},
|
353
353
|
})
|
354
354
|
end
|
355
|
+
|
356
|
+
it 'allows to exclude linkages for relationships' do
|
357
|
+
long_comments = create_list(:long_comment, 2)
|
358
|
+
post = create(:post, :with_author, long_comments: long_comments)
|
359
|
+
primary_data = serialize_primary(post, { serializer: MyApp::PostSerializerWithoutIncludeLinks })
|
360
|
+
expect(primary_data).to eq({
|
361
|
+
'id' => '1',
|
362
|
+
'type' => 'posts',
|
363
|
+
'attributes' => {
|
364
|
+
'title' => 'Title for Post 1'
|
365
|
+
},
|
366
|
+
'links' => {
|
367
|
+
'self' => '/posts/1',
|
368
|
+
},
|
369
|
+
'relationships' => {
|
370
|
+
'author' => {
|
371
|
+
},
|
372
|
+
'long-comments' => {
|
373
|
+
},
|
374
|
+
}
|
375
|
+
})
|
376
|
+
end
|
377
|
+
|
378
|
+
it 'allows to include data for relationships' do
|
379
|
+
long_comments = create_list(:long_comment, 2)
|
380
|
+
post = create(:post, :with_author, long_comments: long_comments)
|
381
|
+
primary_data = serialize_primary(post, { serializer: MyApp::PostSerializerWithIncludeData })
|
382
|
+
expect(primary_data).to eq({
|
383
|
+
'id' => '1',
|
384
|
+
'type' => 'posts',
|
385
|
+
'attributes' => {
|
386
|
+
'title' => 'Title for Post 1'
|
387
|
+
},
|
388
|
+
'links' => {
|
389
|
+
'self' => '/posts/1',
|
390
|
+
},
|
391
|
+
'relationships' => {
|
392
|
+
'author' => {
|
393
|
+
'links' => {
|
394
|
+
'self' => '/posts/1/relationships/author',
|
395
|
+
'related' => '/posts/1/author'
|
396
|
+
},
|
397
|
+
'data' => {
|
398
|
+
'type' => 'users',
|
399
|
+
'id' => '1'
|
400
|
+
}
|
401
|
+
},
|
402
|
+
'long-comments' => {
|
403
|
+
'links' => {
|
404
|
+
'self' => '/posts/1/relationships/long-comments',
|
405
|
+
'related' => '/posts/1/long-comments'
|
406
|
+
},
|
407
|
+
'data' => [
|
408
|
+
{
|
409
|
+
'type' => 'long-comments',
|
410
|
+
'id' => '1'
|
411
|
+
},
|
412
|
+
{
|
413
|
+
'type' => 'long-comments',
|
414
|
+
'id' => '2'
|
415
|
+
}
|
416
|
+
]
|
417
|
+
},
|
418
|
+
}
|
419
|
+
})
|
420
|
+
end
|
355
421
|
end
|
356
422
|
|
357
423
|
# The members data and errors MUST NOT coexist in the same document.
|
data/spec/support/serializers.rb
CHANGED
@@ -94,7 +94,6 @@ module MyApp
|
|
94
94
|
|
95
95
|
class PostSerializerWithMetadata
|
96
96
|
include JSONAPI::Serializer
|
97
|
-
include JSONAPI::Serializer
|
98
97
|
|
99
98
|
attribute :title
|
100
99
|
attribute :long_content do
|
@@ -113,6 +112,32 @@ module MyApp
|
|
113
112
|
end
|
114
113
|
end
|
115
114
|
|
115
|
+
class PostSerializerWithoutIncludeLinks
|
116
|
+
include JSONAPI::Serializer
|
117
|
+
|
118
|
+
attribute :title
|
119
|
+
|
120
|
+
has_one :author, include_links: false
|
121
|
+
has_many :long_comments, include_links: false
|
122
|
+
|
123
|
+
def type
|
124
|
+
:posts
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
class PostSerializerWithIncludeData
|
129
|
+
include JSONAPI::Serializer
|
130
|
+
|
131
|
+
attribute :title
|
132
|
+
|
133
|
+
has_one :author, include_data: true
|
134
|
+
has_many :long_comments, include_data: true
|
135
|
+
|
136
|
+
def type
|
137
|
+
:posts
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
116
141
|
class PostSerializerWithContext < PostSerializer
|
117
142
|
attribute :body, if: :show_body?, unless: :hide_body?
|
118
143
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi-serializers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Fotinakis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04-
|
11
|
+
date: 2016-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|