barley 0.1.0 → 0.3.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/README.md +61 -26
- data/lib/barley/serializable.rb +2 -2
- data/lib/barley/serializer.rb +75 -52
- data/lib/barley/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: be82895a01fc1f0be3170a9a105b7fdf20b7e98d31a77c74c5d9f67068814dec
|
|
4
|
+
data.tar.gz: 276dcc80814079aed898b1e4d1d9e5b6bf3bc4b8b6b86f2b5cff701961d2b877
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9f3482dc0562669991a64403c9c5cee510d61cc5ec79affa3715eb203ac1a48f1f15c676778d380eccbfe6efc57281eae6c179ab4378a62d35c31b0fd65529ea
|
|
7
|
+
data.tar.gz: b9d2a98edf8704acf8b8466042b924b771384e1756fd06f9d23939f9bd0fb4368a4934303057edd0a53d0c8f487dc93c10649e39fe17b3031189f383a668ec54
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Barley is a dead simple, fast, and efficient ActiveModel JSON serializer.
|
|
4
4
|
|
|
5
|
-
Cerealize your ActiveModel objects into flat
|
|
5
|
+
Cerealize your ActiveModel objects into flat hashes with a dead simple, yet versatile DSL, and caching baked in. Our daily bread is to make your API faster.
|
|
6
6
|
|
|
7
7
|
You don't believe us? Check out the [benchmarks](#benchmarks). 😎
|
|
8
8
|
|
|
@@ -21,10 +21,19 @@ Then define your attributes and associations in a serializer class.
|
|
|
21
21
|
```ruby
|
|
22
22
|
# /app/serializers/user_serializer.rb
|
|
23
23
|
class UserSerializer < Barley::Serializer
|
|
24
|
-
attributes :id, :name,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
attributes :id, :name,
|
|
25
|
+
attribute :email # single attribute
|
|
26
|
+
|
|
27
|
+
many :posts # relations
|
|
28
|
+
one :group, serializer: CustomGroupSerializer # custom serializer
|
|
29
|
+
many :related_users, key: :friends, cache: true # custom key, and caching
|
|
30
|
+
one :profile, cache: { expires_in: 1.day } do # cache definition, and block (on associations) for nested, on-the-fly serializer
|
|
31
|
+
attributes :avatar, :social_url
|
|
32
|
+
attribute :badges do
|
|
33
|
+
object.badges.map(&:display_name) # use object in a block to return custom code
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
28
37
|
end
|
|
29
38
|
```
|
|
30
39
|
|
|
@@ -92,6 +101,12 @@ You can also define a custom attribute with a block. You will have a `object` va
|
|
|
92
101
|
end
|
|
93
102
|
```
|
|
94
103
|
|
|
104
|
+
You can also set a custom key name for the attribute with the `key_name` option.
|
|
105
|
+
|
|
106
|
+
```ruby
|
|
107
|
+
attribute :updated_at, key: :last_change
|
|
108
|
+
```
|
|
109
|
+
|
|
95
110
|
### Associations
|
|
96
111
|
|
|
97
112
|
#### One-to-one
|
|
@@ -101,14 +116,6 @@ You can define a one-to-one association with the `one` macro.
|
|
|
101
116
|
one :group
|
|
102
117
|
```
|
|
103
118
|
|
|
104
|
-
You can also define a custom association with a block. You will have a `object` variable available in the block. It is the object you are serializing.
|
|
105
|
-
|
|
106
|
-
```ruby
|
|
107
|
-
one :group do
|
|
108
|
-
object.group.name
|
|
109
|
-
end
|
|
110
|
-
```
|
|
111
|
-
|
|
112
119
|
##### Custom serializer and caching
|
|
113
120
|
You can define a custom serializer for the association with the `serializer` option, and / or caching options with the `cache` option.
|
|
114
121
|
|
|
@@ -128,9 +135,15 @@ class UserSerializer < Barley::Serializer
|
|
|
128
135
|
attributes :id, :name
|
|
129
136
|
end
|
|
130
137
|
end
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
##### Key name
|
|
131
141
|
|
|
142
|
+
You can also pass a key name for the association with the `key_name` option.
|
|
143
|
+
|
|
144
|
+
```ruby
|
|
145
|
+
one :group, key_name: :team
|
|
132
146
|
```
|
|
133
|
-
end
|
|
134
147
|
|
|
135
148
|
#### One-to-many
|
|
136
149
|
You can define a one-to-many association with the `many` macro.
|
|
@@ -139,20 +152,38 @@ You can define a one-to-many association with the `many` macro.
|
|
|
139
152
|
many :posts
|
|
140
153
|
```
|
|
141
154
|
|
|
142
|
-
|
|
155
|
+
##### Custom serializer and caching
|
|
156
|
+
|
|
157
|
+
You can define a custom serializer for the association with the `serializer` option, and / or caching options with the `cache` option.
|
|
143
158
|
|
|
144
159
|
```ruby
|
|
145
|
-
many :posts
|
|
146
|
-
object.posts.map(&:title)
|
|
147
|
-
end
|
|
160
|
+
many :posts, serializer: CustomPostSerializer, cache: { expires_in: 1.hour }
|
|
148
161
|
```
|
|
149
162
|
|
|
150
|
-
#####
|
|
163
|
+
##### Key name
|
|
164
|
+
You can also pass a key name for the association with the `key_name` option.
|
|
151
165
|
|
|
152
|
-
|
|
166
|
+
```ruby
|
|
167
|
+
many :posts, key_name: :articles
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Associations with blocks
|
|
171
|
+
Feel like using a block to define your associations? You can do that too.
|
|
153
172
|
|
|
154
173
|
```ruby
|
|
155
|
-
|
|
174
|
+
one :group do
|
|
175
|
+
attributes :id, :name
|
|
176
|
+
end
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
```ruby
|
|
180
|
+
many :posts do
|
|
181
|
+
attributes :id, :title, :body
|
|
182
|
+
|
|
183
|
+
one :author do
|
|
184
|
+
attributes :name, :email
|
|
185
|
+
end
|
|
186
|
+
end
|
|
156
187
|
```
|
|
157
188
|
|
|
158
189
|
## Generators
|
|
@@ -209,9 +240,6 @@ Barley uses the MemoryStore by default. You can change the cache store with the
|
|
|
209
240
|
# /config/initializers/barley.rb
|
|
210
241
|
Barley.configure do |config|
|
|
211
242
|
config.cache_store = ActiveSupport::Cache::RedisCacheStore.new
|
|
212
|
-
# config.cache_store = ActiveSupport::Cache::MemoryStore.new
|
|
213
|
-
# config.cache_store = ActiveSupport::Cache::FileStore.new
|
|
214
|
-
# config.cache_store = Rails.cache
|
|
215
243
|
end
|
|
216
244
|
```
|
|
217
245
|
|
|
@@ -242,15 +270,17 @@ rails generate barley:cerealizer User
|
|
|
242
270
|
|
|
243
271
|
Ah ah ah. This is so funny.
|
|
244
272
|
|
|
273
|
+
*Note: we are thinking about adding a `Surrealizer` class for the most advanced users. Stay tuned.*
|
|
274
|
+
|
|
245
275
|
## JSON:API
|
|
246
|
-
|
|
276
|
+
Barley does not serialize to the JSON:API standard. We prefer to keep it simple and fast.
|
|
247
277
|
|
|
248
278
|
## Benchmarks
|
|
249
279
|
This gem is blazing fast and efficient. It is 2 to 3 times faster than [ActiveModel::Serializer](https://github.com/rails-api/active_model_serializers) and twice as fast as [FastJsonapi](https://github.com/Netflix/fast_jsonapi). Memory object allocation is also much lower.
|
|
250
280
|
|
|
251
281
|
With caching enabled, it is just mind-blowing. We think. *Disclaimer: we do not serialize to the JSON:API standard, so that might be the reason why we are so fast.*
|
|
252
282
|
|
|
253
|
-
This is the result we get with the benchmark script used in the AMS repo on an Apple Silicon M1Pro processor.
|
|
283
|
+
This is the result we get with the benchmark script used in the AMS repo on an Apple Silicon M1Pro processor. [Check it out for yourself here](https://github.com/MoskitoHero/active_model_serializers/tree/benchmarks).
|
|
254
284
|
|
|
255
285
|
```shell
|
|
256
286
|
bundle exec ruby benchmark.rb
|
|
@@ -330,3 +360,8 @@ ams : 1299674 allocated - 28.20x more
|
|
|
330
360
|
|
|
331
361
|
## License
|
|
332
362
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
363
|
+
|
|
364
|
+
## Credits
|
|
365
|
+
Barley is brought to you by the developer team from [StockPro](https://www.stock-pro.fr/).
|
|
366
|
+
|
|
367
|
+
[](https://www.stock-pro.fr/)
|
data/lib/barley/serializable.rb
CHANGED
|
@@ -33,9 +33,9 @@ module Barley
|
|
|
33
33
|
included do
|
|
34
34
|
serializer "#{self}Serializer".constantize
|
|
35
35
|
|
|
36
|
-
def as_json(serializer: nil, cache: false)
|
|
36
|
+
def as_json(serializer: nil, cache: false, root: false)
|
|
37
37
|
serializer ||= self.serializer.class
|
|
38
|
-
serializer.new(self, cache: cache).
|
|
38
|
+
serializer.new(self, cache: cache, root: root).serializable_hash
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
end
|
data/lib/barley/serializer.rb
CHANGED
|
@@ -4,75 +4,90 @@ module Barley
|
|
|
4
4
|
class Serializer
|
|
5
5
|
attr_accessor :object
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
else
|
|
16
|
-
[cache, nil]
|
|
7
|
+
class << self
|
|
8
|
+
def attributes(*keys)
|
|
9
|
+
keys.each do |key|
|
|
10
|
+
define_method(key) do
|
|
11
|
+
object.send(key)
|
|
12
|
+
end
|
|
13
|
+
set_class_iv(:@defined_attributes, key)
|
|
14
|
+
end
|
|
17
15
|
end
|
|
18
|
-
end
|
|
19
16
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
def attribute(key, key_name: nil, &block)
|
|
18
|
+
key_name ||= key
|
|
19
|
+
if block
|
|
20
|
+
define_method(key_name) do
|
|
21
|
+
instance_eval(&block)
|
|
22
|
+
end
|
|
23
|
+
else
|
|
24
|
+
define_method(key_name) do
|
|
25
|
+
object.send(key)
|
|
26
|
+
end
|
|
24
27
|
end
|
|
25
|
-
set_class_iv(:@defined_attributes,
|
|
28
|
+
set_class_iv(:@defined_attributes, key_name)
|
|
26
29
|
end
|
|
27
|
-
end
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
def one(key, key_name: nil, serializer: nil, cache: false, &block)
|
|
32
|
+
key_name ||= key
|
|
33
|
+
if block
|
|
34
|
+
serializer = Class.new(Barley::Serializer) do
|
|
35
|
+
instance_eval(&block)
|
|
36
|
+
end
|
|
33
37
|
end
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
define_method(key_name) do
|
|
39
|
+
element = object.send(key)
|
|
40
|
+
return {} if element.nil?
|
|
41
|
+
|
|
42
|
+
el_serializer = serializer || element.serializer.class
|
|
43
|
+
el_serializer.new(element, cache: cache).serializable_hash
|
|
37
44
|
end
|
|
45
|
+
set_class_iv(:@defined_attributes, key_name)
|
|
38
46
|
end
|
|
39
|
-
set_class_iv(:@defined_attributes, key)
|
|
40
|
-
end
|
|
41
47
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
def many(key, key_name: nil, serializer: nil, cache: false, &block)
|
|
49
|
+
key_name ||= key
|
|
50
|
+
if block
|
|
51
|
+
serializer = Class.new(Barley::Serializer) do
|
|
52
|
+
instance_eval(&block)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
define_method(key_name) do
|
|
56
|
+
elements = object.send(key)
|
|
57
|
+
return [] if elements.empty?
|
|
45
58
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
59
|
+
el_serializer = serializer || elements.first.serializer.class
|
|
60
|
+
elements.map { |element| el_serializer.new(element, cache: cache).serializable_hash }.reject(&:blank?)
|
|
61
|
+
end
|
|
62
|
+
set_class_iv(:@defined_attributes, key_name)
|
|
63
|
+
end
|
|
50
64
|
|
|
51
|
-
|
|
52
|
-
|
|
65
|
+
def set_class_iv(iv, key)
|
|
66
|
+
instance_variable_defined?(iv) ? instance_variable_get(iv) << key : instance_variable_set(iv, [key])
|
|
53
67
|
end
|
|
54
|
-
set_class_iv(:@defined_attributes, key)
|
|
55
68
|
end
|
|
56
69
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
70
|
+
# @example with cache
|
|
71
|
+
# Barley::Serializer.new(object, cache: true)
|
|
72
|
+
# @example with cache and expires_in
|
|
73
|
+
# Barley::Serializer.new(object, cache: {expires_in: 1.hour})
|
|
74
|
+
def initialize(object, cache: false, root: false)
|
|
75
|
+
@object = object
|
|
76
|
+
@root = root
|
|
77
|
+
@cache, @expires_in = if cache.is_a?(Hash)
|
|
78
|
+
[true, cache[:expires_in]]
|
|
79
|
+
else
|
|
80
|
+
[cache, nil]
|
|
64
81
|
end
|
|
65
|
-
set_class_iv(:@defined_attributes, key)
|
|
66
82
|
end
|
|
67
83
|
|
|
68
|
-
def
|
|
84
|
+
def serializable_hash
|
|
69
85
|
if @cache
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
_as_json
|
|
86
|
+
Barley::Cache.fetch(cache_base_key, expires_in: @expires_in) do
|
|
87
|
+
_serializable_hash
|
|
73
88
|
end
|
|
74
89
|
else
|
|
75
|
-
|
|
90
|
+
_serializable_hash
|
|
76
91
|
end
|
|
77
92
|
end
|
|
78
93
|
|
|
@@ -83,21 +98,29 @@ module Barley
|
|
|
83
98
|
private
|
|
84
99
|
|
|
85
100
|
def cache_base_key
|
|
86
|
-
|
|
101
|
+
if object.updated_at.present?
|
|
102
|
+
"#{object.class.name&.underscore}/#{object.id}/#{object.updated_at&.to_i}/barley_cache/"
|
|
103
|
+
else
|
|
104
|
+
"#{object.class.name&.underscore}/#{object.id}/barley_cache/"
|
|
105
|
+
end
|
|
87
106
|
end
|
|
88
107
|
|
|
89
108
|
def defined_attributes
|
|
90
109
|
self.class.instance_variable_get(:@defined_attributes)
|
|
91
110
|
end
|
|
92
111
|
|
|
93
|
-
def
|
|
112
|
+
def _serializable_hash
|
|
94
113
|
hash = {}
|
|
95
114
|
|
|
96
115
|
defined_attributes.each do |key|
|
|
97
116
|
hash[key] = send(key)
|
|
98
117
|
end
|
|
99
118
|
|
|
100
|
-
hash
|
|
119
|
+
@root ? {root_key => hash} : hash
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def root_key
|
|
123
|
+
object.class.name.underscore.to_sym
|
|
101
124
|
end
|
|
102
125
|
end
|
|
103
126
|
end
|
data/lib/barley/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: barley
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Cedric Delalande
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-10-
|
|
11
|
+
date: 2023-10-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|