barley 0.1.0 → 0.3.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 +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
|
+
[![Barley is brought to you by StockPro](img/stockpro.png)](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
|