jsonapi-serializer 2.0.0 → 2.1.0
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/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
|