jsonapi-serializer 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +2 -2
- data/README.md +62 -27
- data/lib/fast_jsonapi/instrumentation.rb +7 -2
- data/lib/fast_jsonapi/instrumentation/skylight.rb +3 -2
- data/lib/fast_jsonapi/object_serializer.rb +18 -24
- data/lib/fast_jsonapi/relationship.rb +14 -2
- data/lib/fast_jsonapi/serialization_core.rb +86 -38
- data/lib/generators/serializer/templates/serializer.rb.tt +1 -1
- data/lib/jsonapi/serializer/instrumentation.rb +27 -0
- data/lib/jsonapi/serializer/version.rb +1 -1
- metadata +6 -10
- data/lib/fast_jsonapi/instrumentation/serializable_hash.rb +0 -13
- data/lib/fast_jsonapi/instrumentation/serialized_json.rb +0 -13
- data/lib/fast_jsonapi/instrumentation/skylight/normalizers/base.rb +0 -7
- data/lib/fast_jsonapi/instrumentation/skylight/normalizers/serializable_hash.rb +0 -20
- data/lib/fast_jsonapi/instrumentation/skylight/normalizers/serialized_json.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 017a78c672880bd4e5c71443b4d89e6755c2819c2e255fe0fabc634b2eb03b6f
|
4
|
+
data.tar.gz: 849735cbc53db74e8fe00b0b6e35372ee63402c04e8a74df9693d81ab4d10fee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35f5960d308078c06bdbdd9d4bd0b735ae8d409f4637b595cb3e1a51b53fea1aaaa37bc7ed871fcdff46429463a0644b30d0626156ab39894e1a0b4fe6dadf16
|
7
|
+
data.tar.gz: 70d5947d310735e7faf1839db897fc7227af7b7407b185fa30ec9622214f78600b86bb419c1c9c16c838d6da5606c6104b566d1bbe6d86817e3f30b70301c647
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Apache License
|
2
2
|
Version 2.0, January 2004
|
3
|
-
|
3
|
+
https://www.apache.org/licenses/
|
4
4
|
|
5
5
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
6
6
|
|
@@ -192,7 +192,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
192
|
you may not use this file except in compliance with the License.
|
193
193
|
You may obtain a copy of the License at
|
194
194
|
|
195
|
-
|
195
|
+
https://www.apache.org/licenses/LICENSE-2.0
|
196
196
|
|
197
197
|
Unless required by applicable law or agreed to in writing, software
|
198
198
|
distributed under the License is distributed on an "AS IS" BASIS,
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# JSON:API Serialization Library
|
2
2
|
|
3
|
-
A fast [JSON:API](
|
3
|
+
A fast [JSON:API](https://jsonapi.org/) serializer for Ruby Objects.
|
4
4
|
|
5
5
|
Previously this project was called **fast_jsonapi**, we forked the project
|
6
6
|
and renamed it to **jsonapi/serializer** in order to keep it alive.
|
@@ -38,6 +38,7 @@ article in the `docs` folder for any questions related to methodology.
|
|
38
38
|
* [Specifying a Relationship Serializer](#specifying-a-relationship-serializer)
|
39
39
|
* [Sparse Fieldsets](#sparse-fieldsets)
|
40
40
|
* [Using helper methods](#using-helper-methods)
|
41
|
+
* [Performance Instrumentation](#performance-instrumentation)
|
41
42
|
* [Contributing](#contributing)
|
42
43
|
|
43
44
|
|
@@ -257,18 +258,18 @@ class MovieSerializer
|
|
257
258
|
link :self, :url
|
258
259
|
|
259
260
|
link :custom_url do |object|
|
260
|
-
"
|
261
|
+
"https://movies.com/#{object.name}-(#{object.year})"
|
261
262
|
end
|
262
263
|
|
263
264
|
link :personalized_url do |object, params|
|
264
|
-
"
|
265
|
+
"https://movies.com/#{object.name}-#{params[:user].reference_code}"
|
265
266
|
end
|
266
267
|
end
|
267
268
|
```
|
268
269
|
|
269
270
|
#### Links on a Relationship
|
270
271
|
|
271
|
-
You can specify [relationship links](
|
272
|
+
You can specify [relationship links](https://jsonapi.org/format/#document-resource-object-relationships) by using the `links:` option on the serializer. Relationship links in JSON API are useful if you want to load a parent document and then load associated documents later due to size constraints (see [related resource links](https://jsonapi.org/format/#document-resource-object-related-resource-links))
|
272
273
|
|
273
274
|
```ruby
|
274
275
|
class MovieSerializer
|
@@ -317,6 +318,23 @@ class MovieSerializer
|
|
317
318
|
end
|
318
319
|
```
|
319
320
|
|
321
|
+
#### Meta on a Relationship
|
322
|
+
|
323
|
+
You can specify [relationship meta](https://jsonapi.org/format/#document-resource-object-relationships) by using the `meta:` option on the serializer. Relationship meta in JSON API is useful if you wish to provide non-standard meta-information about the relationship.
|
324
|
+
|
325
|
+
Meta can be defined either by passing a static hash or by using Proc to the `meta` key. In the latter case, the record and any params passed to the serializer are available inside the Proc as the first and second parameters, respectively.
|
326
|
+
|
327
|
+
|
328
|
+
```ruby
|
329
|
+
class MovieSerializer
|
330
|
+
include JSONAPI::Serializer
|
331
|
+
|
332
|
+
has_many :actors, meta: Proc.new do |movie_record, params|
|
333
|
+
{ count: movie_record.actors.length }
|
334
|
+
end
|
335
|
+
end
|
336
|
+
```
|
337
|
+
|
320
338
|
### Compound Document
|
321
339
|
|
322
340
|
Support for top-level and nested included associations through `options[:include]`.
|
@@ -392,6 +410,25 @@ So for the example above it will call the cache instance like this:
|
|
392
410
|
Rails.cache.fetch(record, namespace: 'jsonapi-serializer', expires_in: 1.hour) { ... }
|
393
411
|
```
|
394
412
|
|
413
|
+
#### Caching and Sparse Fieldsets
|
414
|
+
|
415
|
+
If caching is enabled and fields are provided to the serializer, the fieldset will be appended to the cache key's namespace.
|
416
|
+
|
417
|
+
For example, given the following serializer definition and instance:
|
418
|
+
```ruby
|
419
|
+
class ActorSerializer
|
420
|
+
include JSONAPI::Serializer
|
421
|
+
|
422
|
+
attributes :first_name, :last_name
|
423
|
+
|
424
|
+
cache_options store: Rails.cache, namespace: 'jsonapi-serializer', expires_in: 1.hour
|
425
|
+
end
|
426
|
+
|
427
|
+
serializer = ActorSerializer.new(actor, { fields: { actor: [:first_name] } })
|
428
|
+
```
|
429
|
+
|
430
|
+
The following cache namespace will be generated: `'jsonapi-serializer-fieldset:first_name'`.
|
431
|
+
|
395
432
|
### Params
|
396
433
|
|
397
434
|
In some cases, attribute values might require more information than what is
|
@@ -452,6 +489,13 @@ class MovieSerializer
|
|
452
489
|
# The director will be serialized only if the :admin key of params is true
|
453
490
|
params && params[:admin] == true
|
454
491
|
}
|
492
|
+
|
493
|
+
# Custom attribute `name_year` will only be serialized if both `name` and `year` fields are present
|
494
|
+
attribute :name_year, if: Proc.new { |record|
|
495
|
+
record.name.present? && record.year.present?
|
496
|
+
} do |object|
|
497
|
+
"#{object.name} - #{object.year}"
|
498
|
+
end
|
455
499
|
end
|
456
500
|
|
457
501
|
# ...
|
@@ -619,36 +663,27 @@ serializer | Set custom Serializer for a relationship | `has_many :actors, seria
|
|
619
663
|
polymorphic | Allows different record types for a polymorphic association | `has_many :targets, polymorphic: true`
|
620
664
|
polymorphic | Sets custom record types for each object class in a polymorphic association | `has_many :targets, polymorphic: { Person => :person, Group => :group }`
|
621
665
|
|
622
|
-
### Instrumentation
|
666
|
+
### Performance Instrumentation
|
623
667
|
|
624
|
-
|
625
|
-
|
626
|
-
```ruby
|
627
|
-
require 'fast_jsonapi/instrumentation/skylight'
|
628
|
-
```
|
668
|
+
Performance instrumentation is available by using the
|
669
|
+
`active_support/notifications`.
|
629
670
|
|
630
|
-
|
671
|
+
To enable it, include the module in your serializer class:
|
631
672
|
|
632
673
|
```ruby
|
633
|
-
require '
|
634
|
-
|
635
|
-
|
636
|
-
The two instrumented notifications are supplied by these two constants:
|
637
|
-
* `FastJsonapi::ObjectSerializer::SERIALIZABLE_HASH_NOTIFICATION`
|
638
|
-
* `FastJsonapi::ObjectSerializer::SERIALIZED_JSON_NOTIFICATION`
|
674
|
+
require 'jsonapi/serializer'
|
675
|
+
require 'jsonapi/serializer/instrumentation'
|
639
676
|
|
640
|
-
|
677
|
+
class MovieSerializer
|
678
|
+
include JSONAPI::Serializer
|
679
|
+
include JSONAPI::Serializer::Instrumentation
|
641
680
|
|
642
|
-
|
643
|
-
|
644
|
-
require 'fast_jsonapi/instrumentation/serialized_json'
|
681
|
+
# ...
|
682
|
+
end
|
645
683
|
```
|
646
684
|
|
647
|
-
|
648
|
-
|
649
|
-
require 'fast_jsonapi/instrumentation/skylight/normalizers/serializable_hash'
|
650
|
-
require 'fast_jsonapi/instrumentation/skylight/normalizers/serialized_json'
|
651
|
-
```
|
685
|
+
[Skylight](https://www.skylight.io/) integration is also available and
|
686
|
+
supported by us, follow the Skylight documentation to enable it.
|
652
687
|
|
653
688
|
### Running Tests
|
654
689
|
The project has and requires unit tests, functional tests and performance
|
@@ -665,4 +700,4 @@ pull request creation processes.
|
|
665
700
|
|
666
701
|
This project is intended to be a safe, welcoming space for collaboration, and
|
667
702
|
contributors are expected to adhere to the
|
668
|
-
[Contributor Covenant](
|
703
|
+
[Contributor Covenant](https://contributor-covenant.org) code of conduct.
|
@@ -1,2 +1,7 @@
|
|
1
|
-
require '
|
2
|
-
|
1
|
+
require 'jsonapi/serializer/instrumentation'
|
2
|
+
|
3
|
+
warn(
|
4
|
+
'DEPRECATION: Performance instrumentation is no longer automatic. See: ' \
|
5
|
+
'https://github.com/jsonapi-serializer/jsonapi-serializer' \
|
6
|
+
'#performance-instrumentation'
|
7
|
+
)
|
@@ -1,2 +1,3 @@
|
|
1
|
-
require '
|
2
|
-
|
1
|
+
require 'skylight'
|
2
|
+
|
3
|
+
warn('DEPRECATION: Skylight support was moved into the `skylight` gem.')
|
@@ -15,8 +15,6 @@ module FastJsonapi
|
|
15
15
|
extend ActiveSupport::Concern
|
16
16
|
include SerializationCore
|
17
17
|
|
18
|
-
SERIALIZABLE_HASH_NOTIFICATION = 'render.fast_jsonapi.serializable_hash'
|
19
|
-
SERIALIZED_JSON_NOTIFICATION = 'render.fast_jsonapi.serialized_json'
|
20
18
|
TRANSFORMS_MAPPING = {
|
21
19
|
camel: :camelize,
|
22
20
|
camel_lower: [:camelize, :lower],
|
@@ -36,7 +34,9 @@ module FastJsonapi
|
|
36
34
|
end
|
37
35
|
|
38
36
|
def serializable_hash
|
39
|
-
|
37
|
+
if self.class.is_collection?(@resource, @is_collection)
|
38
|
+
return hash_for_collection
|
39
|
+
end
|
40
40
|
|
41
41
|
hash_for_one_record
|
42
42
|
end
|
@@ -80,7 +80,7 @@ module FastJsonapi
|
|
80
80
|
|
81
81
|
return if options.blank?
|
82
82
|
|
83
|
-
@known_included_objects =
|
83
|
+
@known_included_objects = Set.new
|
84
84
|
@meta = options[:meta]
|
85
85
|
@links = options[:links]
|
86
86
|
@is_collection = options[:is_collection]
|
@@ -105,13 +105,16 @@ module FastJsonapi
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
-
|
109
|
-
|
108
|
+
class_methods do
|
109
|
+
# Detects a collection/enumerable
|
110
|
+
#
|
111
|
+
# @return [TrueClass] on a successful detection
|
112
|
+
def is_collection?(resource, force_is_collection = nil)
|
113
|
+
return force_is_collection unless force_is_collection.nil?
|
110
114
|
|
111
|
-
|
112
|
-
|
115
|
+
resource.is_a?(Enumerable) && !resource.respond_to?(:each_pair)
|
116
|
+
end
|
113
117
|
|
114
|
-
class_methods do
|
115
118
|
def inherited(subclass)
|
116
119
|
super(subclass)
|
117
120
|
subclass.attributes_to_serialize = attributes_to_serialize.dup if attributes_to_serialize.present?
|
@@ -283,6 +286,7 @@ module FastJsonapi
|
|
283
286
|
polymorphic: polymorphic,
|
284
287
|
conditional_proc: options[:if],
|
285
288
|
transform_method: @transform_method,
|
289
|
+
meta: options[:meta],
|
286
290
|
links: options[:links],
|
287
291
|
lazy_load_data: options[:lazy_load_data]
|
288
292
|
)
|
@@ -336,21 +340,11 @@ module FastJsonapi
|
|
336
340
|
def validate_includes!(includes)
|
337
341
|
return if includes.blank?
|
338
342
|
|
339
|
-
includes.each do |include_item|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
raise ArgumentError, "#{parsed_include} is not specified as a relationship on #{klass.name}" unless relationship_to_include
|
345
|
-
|
346
|
-
if relationship_to_include.static_serializer
|
347
|
-
klass = relationship_to_include.static_serializer
|
348
|
-
else
|
349
|
-
# the serializer may change based on the object (e.g. polymorphic relationships),
|
350
|
-
# so inner relationships cannot be validated
|
351
|
-
break
|
352
|
-
end
|
353
|
-
end
|
343
|
+
parse_includes_list(includes).keys.each do |include_item|
|
344
|
+
relationship_to_include = relationships_to_serialize[include_item]
|
345
|
+
raise ArgumentError, "#{include_item} is not specified as a relationship on #{name}" unless relationship_to_include
|
346
|
+
|
347
|
+
relationship_to_include.static_serializer # called for a side-effect to check for a known serializer class.
|
354
348
|
end
|
355
349
|
end
|
356
350
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module FastJsonapi
|
2
2
|
class Relationship
|
3
|
-
attr_reader :owner, :key, :name, :id_method_name, :record_type, :object_method_name, :object_block, :serializer, :relationship_type, :cached, :polymorphic, :conditional_proc, :transform_method, :links, :lazy_load_data
|
3
|
+
attr_reader :owner, :key, :name, :id_method_name, :record_type, :object_method_name, :object_block, :serializer, :relationship_type, :cached, :polymorphic, :conditional_proc, :transform_method, :links, :meta, :lazy_load_data
|
4
4
|
|
5
5
|
def initialize(
|
6
6
|
owner:,
|
@@ -17,6 +17,7 @@ module FastJsonapi
|
|
17
17
|
conditional_proc:,
|
18
18
|
transform_method:,
|
19
19
|
links:,
|
20
|
+
meta:,
|
20
21
|
lazy_load_data: false
|
21
22
|
)
|
22
23
|
@owner = owner
|
@@ -33,6 +34,7 @@ module FastJsonapi
|
|
33
34
|
@conditional_proc = conditional_proc
|
34
35
|
@transform_method = transform_method
|
35
36
|
@links = links || {}
|
37
|
+
@meta = meta || {}
|
36
38
|
@lazy_load_data = lazy_load_data
|
37
39
|
@record_types_for = {}
|
38
40
|
@serializers_for_name = {}
|
@@ -44,6 +46,8 @@ module FastJsonapi
|
|
44
46
|
|
45
47
|
output_hash[key] = {}
|
46
48
|
output_hash[key][:data] = ids_hash_from_record_and_relationship(record, serialization_params) || empty_case unless lazy_load_data && !included
|
49
|
+
|
50
|
+
add_meta_hash(record, serialization_params, output_hash) if meta.present?
|
47
51
|
add_links_hash(record, serialization_params, output_hash) if links.present?
|
48
52
|
end
|
49
53
|
end
|
@@ -146,11 +150,19 @@ module FastJsonapi
|
|
146
150
|
record.public_send(links)
|
147
151
|
else
|
148
152
|
links.each_with_object({}) do |(key, method), hash|
|
149
|
-
Link.new(key: key, method: method).serialize(record, params, hash)
|
153
|
+
Link.new(key: key, method: method).serialize(record, params, hash)
|
150
154
|
end
|
151
155
|
end
|
152
156
|
end
|
153
157
|
|
158
|
+
def add_meta_hash(record, params, output_hash)
|
159
|
+
output_hash[key][:meta] = if meta.is_a?(Proc)
|
160
|
+
FastJsonapi.call_proc(meta, record, params)
|
161
|
+
else
|
162
|
+
meta
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
154
166
|
def run_key_transform(input)
|
155
167
|
if transform_method.present?
|
156
168
|
input.to_s.send(*transform_method).to_sym
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'active_support/concern'
|
4
|
+
require 'digest/sha1'
|
4
5
|
|
5
6
|
module FastJsonapi
|
6
7
|
MandatoryField = Class.new(StandardError)
|
@@ -66,7 +67,8 @@ module FastJsonapi
|
|
66
67
|
|
67
68
|
def record_hash(record, fieldset, includes_list, params = {})
|
68
69
|
if cache_store_instance
|
69
|
-
|
70
|
+
cache_opts = record_cache_options(cache_store_options, fieldset, includes_list, params)
|
71
|
+
record_hash = cache_store_instance.fetch(record, **cache_opts) do
|
70
72
|
temp_hash = id_hash(id_from_record(record, params), record_type, true)
|
71
73
|
temp_hash[:attributes] = attributes_hash(record, fieldset, params) if attributes_to_serialize.present?
|
72
74
|
temp_hash[:relationships] = {}
|
@@ -86,6 +88,37 @@ module FastJsonapi
|
|
86
88
|
record_hash
|
87
89
|
end
|
88
90
|
|
91
|
+
# Cache options helper. Use it to adapt cache keys/rules.
|
92
|
+
#
|
93
|
+
# If a fieldset is specified, it modifies the namespace to include the
|
94
|
+
# fields from the fieldset.
|
95
|
+
#
|
96
|
+
# @param options [Hash] default cache options
|
97
|
+
# @param fieldset [Array, nil] passed fieldset values
|
98
|
+
# @param includes_list [Array, nil] passed included values
|
99
|
+
# @param params [Hash] the serializer params
|
100
|
+
#
|
101
|
+
# @return [Hash] processed options hash
|
102
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
103
|
+
def record_cache_options(options, fieldset, includes_list, params)
|
104
|
+
return options unless fieldset
|
105
|
+
|
106
|
+
options = options ? options.dup : {}
|
107
|
+
options[:namespace] ||= 'jsonapi-serializer'
|
108
|
+
|
109
|
+
fieldset_key = fieldset.join('_')
|
110
|
+
|
111
|
+
# Use a fixed-length fieldset key if the current length is more than
|
112
|
+
# the length of a SHA1 digest
|
113
|
+
if fieldset_key.length > 40
|
114
|
+
fieldset_key = Digest::SHA1.hexdigest(fieldset_key)
|
115
|
+
end
|
116
|
+
|
117
|
+
options[:namespace] = "#{options[:namespace]}-fieldset:#{fieldset_key}"
|
118
|
+
options
|
119
|
+
end
|
120
|
+
# rubocop:enable Lint/UnusedMethodArgument
|
121
|
+
|
89
122
|
def id_from_record(record, params)
|
90
123
|
return FastJsonapi.call_proc(record_id, record, params) if record_id.is_a?(Proc)
|
91
124
|
return record.send(record_id) if record_id
|
@@ -94,58 +127,73 @@ module FastJsonapi
|
|
94
127
|
record.id
|
95
128
|
end
|
96
129
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
130
|
+
# It chops out the root association (first part) from each include.
|
131
|
+
#
|
132
|
+
# It keeps an unique list and collects all of the rest of the include
|
133
|
+
# value to hand it off to the next related to include serializer.
|
134
|
+
#
|
135
|
+
# This method will turn that include array into a Hash that looks like:
|
136
|
+
#
|
137
|
+
# {
|
138
|
+
# authors: Set.new([
|
139
|
+
# 'books',
|
140
|
+
# 'books.genre',
|
141
|
+
# 'books.genre.books',
|
142
|
+
# 'books.genre.books.authors',
|
143
|
+
# 'books.genre.books.genre'
|
144
|
+
# ]),
|
145
|
+
# genre: Set.new(['books'])
|
146
|
+
# }
|
147
|
+
#
|
148
|
+
# Because the serializer only cares about the root associations
|
149
|
+
# included, it only needs the first segment of each include
|
150
|
+
# (for books, it's the "authors" and "genre") and it doesn't need to
|
151
|
+
# waste cycles parsing the rest of the include value. That will be done
|
152
|
+
# by the next serializer in line.
|
153
|
+
#
|
154
|
+
# @param includes_list [List] to be parsed
|
155
|
+
# @return [Hash]
|
156
|
+
def parse_includes_list(includes_list)
|
157
|
+
includes_list.each_with_object({}) do |include_item, include_sets|
|
158
|
+
include_base, include_remainder = include_item.to_s.split('.', 2)
|
159
|
+
include_sets[include_base.to_sym] ||= Set.new
|
160
|
+
include_sets[include_base.to_sym] << include_remainder if include_remainder
|
161
|
+
end
|
107
162
|
end
|
108
163
|
|
109
164
|
# includes handler
|
110
165
|
def get_included_records(record, includes_list, known_included_objects, fieldsets, params = {})
|
111
166
|
return unless includes_list.present?
|
167
|
+
return [] unless relationships_to_serialize
|
112
168
|
|
113
|
-
includes_list
|
114
|
-
items = parse_include_item(include_item)
|
115
|
-
remaining_items = remaining_items(items)
|
116
|
-
|
117
|
-
items.each do |item|
|
118
|
-
next unless relationships_to_serialize && relationships_to_serialize[item]
|
169
|
+
includes_list = parse_includes_list(includes_list)
|
119
170
|
|
120
|
-
|
121
|
-
|
171
|
+
includes_list.each_with_object([]) do |include_item, included_records|
|
172
|
+
relationship_item = relationships_to_serialize[include_item.first]
|
122
173
|
|
123
|
-
|
174
|
+
next unless relationship_item&.include_relationship?(record, params)
|
124
175
|
|
125
|
-
|
126
|
-
|
176
|
+
included_objects = Array(relationship_item.fetch_associated_object(record, params))
|
177
|
+
next if included_objects.empty?
|
127
178
|
|
128
|
-
|
179
|
+
static_serializer = relationship_item.static_serializer
|
180
|
+
static_record_type = relationship_item.static_record_type
|
129
181
|
|
130
|
-
|
131
|
-
|
182
|
+
included_objects.each do |inc_obj|
|
183
|
+
serializer = static_serializer || relationship_item.serializer_for(inc_obj, params)
|
184
|
+
record_type = static_record_type || serializer.record_type
|
132
185
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
if remaining_items.present?
|
138
|
-
serializer_records = serializer.get_included_records(inc_obj, remaining_items, known_included_objects, fieldsets, params)
|
139
|
-
included_records.concat(serializer_records) unless serializer_records.empty?
|
140
|
-
end
|
186
|
+
if include_item.last.any?
|
187
|
+
serializer_records = serializer.get_included_records(inc_obj, include_item.last, known_included_objects, fieldsets, params)
|
188
|
+
included_records.concat(serializer_records) unless serializer_records.empty?
|
189
|
+
end
|
141
190
|
|
142
|
-
|
143
|
-
|
191
|
+
code = "#{record_type}_#{serializer.id_from_record(inc_obj, params)}"
|
192
|
+
next if known_included_objects.include?(code)
|
144
193
|
|
145
|
-
|
194
|
+
known_included_objects << code
|
146
195
|
|
147
|
-
|
148
|
-
end
|
196
|
+
included_records << serializer.record_hash(inc_obj, fieldsets[record_type], includes_list, params)
|
149
197
|
end
|
150
198
|
end
|
151
199
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'active_support/notifications'
|
2
|
+
|
3
|
+
module JSONAPI
|
4
|
+
module Serializer
|
5
|
+
# Support for instrumentation
|
6
|
+
module Instrumentation
|
7
|
+
# Performance instrumentation namespace
|
8
|
+
NOTIFICATION_NAMESPACE = 'render.jsonapi-serializer.'.freeze
|
9
|
+
|
10
|
+
# Patch methods to use instrumentation...
|
11
|
+
%w[
|
12
|
+
serializable_hash
|
13
|
+
get_included_records
|
14
|
+
relationships_hash
|
15
|
+
].each do |method_name|
|
16
|
+
define_method(method_name) do |*args|
|
17
|
+
ActiveSupport::Notifications.instrument(
|
18
|
+
NOTIFICATION_NAMESPACE + method_name,
|
19
|
+
{ name: self.class.name, serializer: self.class }
|
20
|
+
) do
|
21
|
+
super(*args)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi-serializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- JSON:API Serializer Community
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
89
|
+
version: 0.0.5
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: 0.0.5
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rake
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -208,12 +208,7 @@ files:
|
|
208
208
|
- lib/fast_jsonapi/attribute.rb
|
209
209
|
- lib/fast_jsonapi/helpers.rb
|
210
210
|
- lib/fast_jsonapi/instrumentation.rb
|
211
|
-
- lib/fast_jsonapi/instrumentation/serializable_hash.rb
|
212
|
-
- lib/fast_jsonapi/instrumentation/serialized_json.rb
|
213
211
|
- lib/fast_jsonapi/instrumentation/skylight.rb
|
214
|
-
- lib/fast_jsonapi/instrumentation/skylight/normalizers/base.rb
|
215
|
-
- lib/fast_jsonapi/instrumentation/skylight/normalizers/serializable_hash.rb
|
216
|
-
- lib/fast_jsonapi/instrumentation/skylight/normalizers/serialized_json.rb
|
217
212
|
- lib/fast_jsonapi/link.rb
|
218
213
|
- lib/fast_jsonapi/object_serializer.rb
|
219
214
|
- lib/fast_jsonapi/railtie.rb
|
@@ -225,8 +220,9 @@ files:
|
|
225
220
|
- lib/generators/serializer/serializer_generator.rb
|
226
221
|
- lib/generators/serializer/templates/serializer.rb.tt
|
227
222
|
- lib/jsonapi/serializer.rb
|
223
|
+
- lib/jsonapi/serializer/instrumentation.rb
|
228
224
|
- lib/jsonapi/serializer/version.rb
|
229
|
-
homepage:
|
225
|
+
homepage: https://github.com/jsonapi-serializer/jsonapi-serializer
|
230
226
|
licenses:
|
231
227
|
- Apache-2.0
|
232
228
|
metadata: {}
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'active_support/notifications'
|
2
|
-
|
3
|
-
module FastJsonapi
|
4
|
-
module ObjectSerializer
|
5
|
-
alias serializable_hash_without_instrumentation serializable_hash
|
6
|
-
|
7
|
-
def serializable_hash
|
8
|
-
ActiveSupport::Notifications.instrument(SERIALIZABLE_HASH_NOTIFICATION, { name: self.class.name }) do
|
9
|
-
serializable_hash_without_instrumentation
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'active_support/notifications'
|
2
|
-
|
3
|
-
module FastJsonapi
|
4
|
-
module ObjectSerializer
|
5
|
-
alias serialized_json_without_instrumentation serialized_json
|
6
|
-
|
7
|
-
def serialized_json
|
8
|
-
ActiveSupport::Notifications.instrument(SERIALIZED_JSON_NOTIFICATION, { name: self.class.name }) do
|
9
|
-
serialized_json_without_instrumentation
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'fast_jsonapi/instrumentation/skylight/normalizers/base'
|
2
|
-
require 'fast_jsonapi/instrumentation/serializable_hash'
|
3
|
-
|
4
|
-
module FastJsonapi
|
5
|
-
module Instrumentation
|
6
|
-
module Skylight
|
7
|
-
module Normalizers
|
8
|
-
class SerializableHash < SKYLIGHT_NORMALIZER_BASE_CLASS
|
9
|
-
register FastJsonapi::ObjectSerializer::SERIALIZABLE_HASH_NOTIFICATION
|
10
|
-
|
11
|
-
CAT = "view.#{FastJsonapi::ObjectSerializer::SERIALIZABLE_HASH_NOTIFICATION}".freeze
|
12
|
-
|
13
|
-
def normalize(_trace, _name, payload)
|
14
|
-
[CAT, payload[:name], nil]
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'fast_jsonapi/instrumentation/skylight/normalizers/base'
|
2
|
-
require 'fast_jsonapi/instrumentation/serializable_hash'
|
3
|
-
|
4
|
-
module FastJsonapi
|
5
|
-
module Instrumentation
|
6
|
-
module Skylight
|
7
|
-
module Normalizers
|
8
|
-
class SerializedJson < SKYLIGHT_NORMALIZER_BASE_CLASS
|
9
|
-
register FastJsonapi::ObjectSerializer::SERIALIZED_JSON_NOTIFICATION
|
10
|
-
|
11
|
-
CAT = "view.#{FastJsonapi::ObjectSerializer::SERIALIZED_JSON_NOTIFICATION}".freeze
|
12
|
-
|
13
|
-
def normalize(_trace, _name, payload)
|
14
|
-
[CAT, payload[:name], nil]
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|