jsonapi-serializers 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -2
- data/README.md +40 -0
- data/jsonapi-serializers.gemspec +1 -1
- data/lib/jsonapi-serializers/serializer.rb +12 -6
- data/lib/jsonapi-serializers/version.rb +1 -1
- data/spec/serializer_spec.rb +44 -0
- data/spec/support/serializers.rb +31 -0
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19d15964189040f00001f5a9deca26a44b21cbe6
|
4
|
+
data.tar.gz: a5b09f36c38933a31ca1b13bcb6bed226ee3a2c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e9effdc7369c2d055bf1533ee7d0f45e364b120e32bf13d34b5fa44faab9f64f40c8161d9470a33c945e83db4055674457c3ee213b4d281400c6dd1f2cc2813
|
7
|
+
data.tar.gz: 0aff7329c2ab1d3bb20a87ffd3c78ad24dcfa74c13d4b634331bb6b87546a2823f5c8546bd715697a6eeb18ee0383d406d6149efab5cb990645a958a1583e6b7
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -19,8 +19,10 @@ This library is up-to-date with the finalized v1 JSON API spec.
|
|
19
19
|
* [More customizations](#more-customizations)
|
20
20
|
* [Base URL](#base-url)
|
21
21
|
* [Root metadata](#root-metadata)
|
22
|
+
* [Root links](#root-links)
|
22
23
|
* [Root errors](#root-errors)
|
23
24
|
* [Explicit serializer discovery](#explicit-serializer-discovery)
|
25
|
+
* [Namespace serializers](#namespace-serializers)
|
24
26
|
* [Relationships](#relationships)
|
25
27
|
* [Compound documents and includes](#compound-documents-and-includes)
|
26
28
|
* [Relationship path handling](#relationship-path-handling)
|
@@ -317,6 +319,14 @@ You can pass a `meta` argument to specify top-level metadata:
|
|
317
319
|
JSONAPI::Serializer.serialize(post, meta: {copyright: 'Copyright 2015 Example Corp.'})
|
318
320
|
```
|
319
321
|
|
322
|
+
### Root links
|
323
|
+
|
324
|
+
You can pass a `links` argument to specify top-level links:
|
325
|
+
|
326
|
+
```ruby
|
327
|
+
JSONAPI::Serializer.serialize(post, links: {self: 'https://example.com/posts'})
|
328
|
+
```
|
329
|
+
|
320
330
|
### Root errors
|
321
331
|
|
322
332
|
You can use `serialize_errors` method in order to specify top-level errors:
|
@@ -361,6 +371,36 @@ end
|
|
361
371
|
|
362
372
|
Now, when a `User` object is serialized, it will use the `SomeOtherNamespace::CustomUserSerializer`.
|
363
373
|
|
374
|
+
### Namespace serializers
|
375
|
+
|
376
|
+
Assume you have an API with multiple versions:
|
377
|
+
|
378
|
+
```ruby
|
379
|
+
module Api
|
380
|
+
module V1
|
381
|
+
class PostSerializer
|
382
|
+
include JSONAPI::Serializer
|
383
|
+
attribute :title
|
384
|
+
end
|
385
|
+
end
|
386
|
+
module V2
|
387
|
+
class PostSerializer
|
388
|
+
include JSONAPI::Serializer
|
389
|
+
attribute :name
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
```
|
394
|
+
|
395
|
+
With the namespace option you can choose which serializer is used.
|
396
|
+
|
397
|
+
```ruby
|
398
|
+
JSONAPI::Serializer.serialize(post, namespace: Api::V1)
|
399
|
+
JSONAPI::Serializer.serialize(post, namespace: Api::V2)
|
400
|
+
```
|
401
|
+
|
402
|
+
This option overrides the `jsonapi_serializer_class_name` method.
|
403
|
+
|
364
404
|
## Relationships
|
365
405
|
|
366
406
|
You can easily specify relationships with the `has_one` and `has_many` directives.
|
data/jsonapi-serializers.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_dependency "activesupport"
|
22
|
-
spec.add_development_dependency "bundler"
|
22
|
+
spec.add_development_dependency "bundler"
|
23
23
|
spec.add_development_dependency "rake", "~> 10.0"
|
24
24
|
spec.add_development_dependency "rspec", "~> 3.2"
|
25
25
|
spec.add_development_dependency "factory_girl", "~> 4.5"
|
@@ -216,20 +216,23 @@ module JSONAPI
|
|
216
216
|
protected :evaluate_attr_or_block
|
217
217
|
end
|
218
218
|
|
219
|
-
def self.find_serializer_class_name(object)
|
219
|
+
def self.find_serializer_class_name(object, options)
|
220
|
+
if options[:namespace]
|
221
|
+
return "#{options[:namespace]}::#{object.class.name}Serializer"
|
222
|
+
end
|
220
223
|
if object.respond_to?(:jsonapi_serializer_class_name)
|
221
224
|
return object.jsonapi_serializer_class_name.to_s
|
222
225
|
end
|
223
226
|
"#{object.class.name}Serializer"
|
224
227
|
end
|
225
228
|
|
226
|
-
def self.find_serializer_class(object)
|
227
|
-
class_name = find_serializer_class_name(object)
|
229
|
+
def self.find_serializer_class(object, options)
|
230
|
+
class_name = find_serializer_class_name(object, options)
|
228
231
|
class_name.constantize
|
229
232
|
end
|
230
233
|
|
231
234
|
def self.find_serializer(object, options)
|
232
|
-
find_serializer_class(object).new(object, options)
|
235
|
+
find_serializer_class(object, options).new(object, options)
|
233
236
|
end
|
234
237
|
|
235
238
|
def self.serialize(objects, options = {})
|
@@ -237,6 +240,7 @@ module JSONAPI
|
|
237
240
|
options[:is_collection] = options.delete('is_collection') || options[:is_collection] || false
|
238
241
|
options[:include] = options.delete('include') || options[:include]
|
239
242
|
options[:serializer] = options.delete('serializer') || options[:serializer]
|
243
|
+
options[:namespace] = options.delete('namespace') || options[:namespace]
|
240
244
|
options[:context] = options.delete('context') || options[:context] || {}
|
241
245
|
options[:skip_collection_check] = options.delete('skip_collection_check') || options[:skip_collection_check] || false
|
242
246
|
options[:base_url] = options.delete('base_url') || options[:base_url]
|
@@ -254,6 +258,7 @@ module JSONAPI
|
|
254
258
|
passthrough_options = {
|
255
259
|
context: options[:context],
|
256
260
|
serializer: options[:serializer],
|
261
|
+
namespace: options[:namespace],
|
257
262
|
include: includes,
|
258
263
|
base_url: options[:base_url]
|
259
264
|
}
|
@@ -316,7 +321,8 @@ module JSONAPI
|
|
316
321
|
included_passthrough_options = {}
|
317
322
|
included_passthrough_options[:base_url] = passthrough_options[:base_url]
|
318
323
|
included_passthrough_options[:context] = passthrough_options[:context]
|
319
|
-
included_passthrough_options[:serializer] = find_serializer_class(data[:object])
|
324
|
+
included_passthrough_options[:serializer] = find_serializer_class(data[:object], options)
|
325
|
+
included_passthrough_options[:namespace] = passthrough_options[:namespace]
|
320
326
|
included_passthrough_options[:include_linkages] = data[:include_linkages]
|
321
327
|
serialize_primary(data[:object], included_passthrough_options)
|
322
328
|
end
|
@@ -352,7 +358,7 @@ module JSONAPI
|
|
352
358
|
end
|
353
359
|
|
354
360
|
def self.serialize_primary(object, options = {})
|
355
|
-
serializer_class = options[:serializer] || find_serializer_class(object)
|
361
|
+
serializer_class = options[:serializer] || find_serializer_class(object, options)
|
356
362
|
|
357
363
|
# Spec: Primary data MUST be either:
|
358
364
|
# - a single resource object or null, for requests that target single resources.
|
data/spec/serializer_spec.rb
CHANGED
@@ -1065,4 +1065,48 @@ describe JSONAPI::Serializer do
|
|
1065
1065
|
end.not_to raise_error
|
1066
1066
|
end
|
1067
1067
|
end
|
1068
|
+
|
1069
|
+
describe 'serializer with namespace option' do
|
1070
|
+
it 'can serialize a simple object with namespace Api::V1' do
|
1071
|
+
user = create(:user)
|
1072
|
+
expect(JSONAPI::Serializer.serialize(user, {namespace: Api::V1})).to eq({
|
1073
|
+
'data' => serialize_primary(user, {serializer: Api::V1::MyApp::UserSerializer}),
|
1074
|
+
})
|
1075
|
+
end
|
1076
|
+
|
1077
|
+
it 'handles recursive loading of relationships with namespaces' do
|
1078
|
+
user = create(:user)
|
1079
|
+
long_comments = create_list(:long_comment, 2, user: user)
|
1080
|
+
post = create(:post, :with_author, long_comments: long_comments)
|
1081
|
+
# Make sure each long-comment has a circular reference back to the post.
|
1082
|
+
long_comments.each { |c| c.post = post }
|
1083
|
+
|
1084
|
+
expected_data = {
|
1085
|
+
'data' => serialize_primary(post, {serializer: Api::V1::MyApp::PostSerializer}),
|
1086
|
+
'included' => [
|
1087
|
+
# Intermediates are included: long-comments, long-comments.post, and long-comments.post.author
|
1088
|
+
# http://jsonapi.org/format/#document-structure-compound-documents
|
1089
|
+
serialize_primary(post.long_comments.first, {
|
1090
|
+
serializer: Api::V1::MyApp::LongCommentSerializer,
|
1091
|
+
include_linkages: ['post']
|
1092
|
+
}),
|
1093
|
+
serialize_primary(post.long_comments.last, {
|
1094
|
+
serializer: Api::V1::MyApp::LongCommentSerializer,
|
1095
|
+
include_linkages: ['post']
|
1096
|
+
}),
|
1097
|
+
serialize_primary(post, {
|
1098
|
+
serializer: Api::V1::MyApp::PostSerializer,
|
1099
|
+
include_linkages: ['author', 'post.long-comments']
|
1100
|
+
}),
|
1101
|
+
serialize_primary(post.author, {serializer: Api::V1::MyApp::UserSerializer})
|
1102
|
+
],
|
1103
|
+
}
|
1104
|
+
includes = ['long-comments.post.author']
|
1105
|
+
actual_data = JSONAPI::Serializer.serialize(post, include: includes, namespace: Api::V1)
|
1106
|
+
# Multiple expectations for better diff output for debugging.
|
1107
|
+
expect(actual_data['data']).to eq(expected_data['data'])
|
1108
|
+
expect(actual_data['included']).to eq(expected_data['included'])
|
1109
|
+
expect(actual_data).to eq(expected_data)
|
1110
|
+
end
|
1111
|
+
end
|
1068
1112
|
end
|
data/spec/support/serializers.rb
CHANGED
@@ -231,3 +231,34 @@ module MyAppOtherNamespace
|
|
231
231
|
attribute :name
|
232
232
|
end
|
233
233
|
end
|
234
|
+
|
235
|
+
module Api
|
236
|
+
module V1
|
237
|
+
module MyApp
|
238
|
+
class UserSerializer
|
239
|
+
include JSONAPI::Serializer
|
240
|
+
|
241
|
+
attribute :name
|
242
|
+
end
|
243
|
+
|
244
|
+
class PostSerializer
|
245
|
+
include JSONAPI::Serializer
|
246
|
+
|
247
|
+
attribute :title
|
248
|
+
|
249
|
+
has_one :author
|
250
|
+
has_many :long_comments
|
251
|
+
end
|
252
|
+
|
253
|
+
class LongCommentSerializer
|
254
|
+
include JSONAPI::Serializer
|
255
|
+
|
256
|
+
attribute :body
|
257
|
+
has_one :user
|
258
|
+
|
259
|
+
# Circular-reference back to post.
|
260
|
+
has_one :post
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
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.14.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-
|
11
|
+
date: 2016-07-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -137,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
137
|
version: '0'
|
138
138
|
requirements: []
|
139
139
|
rubyforge_project:
|
140
|
-
rubygems_version: 2.
|
140
|
+
rubygems_version: 2.4.8
|
141
141
|
signing_key:
|
142
142
|
specification_version: 4
|
143
143
|
summary: Pure Ruby readonly serializers for the JSON:API spec.
|