mini_api 0.1.2 → 0.1.4
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 -0
- data/lib/mini_api/case_transform.rb +33 -0
- data/lib/mini_api/config.rb +11 -0
- data/lib/mini_api/default_responder.rb +29 -2
- data/lib/mini_api/exceptions/case_transform_option_invalid.rb +5 -0
- data/lib/mini_api/model_responder.rb +29 -7
- data/lib/mini_api/relation_responder.rb +9 -0
- data/lib/mini_api/serialization.rb +6 -0
- data/lib/mini_api/version.rb +1 -1
- data/lib/mini_api.rb +14 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf126960ba6eec18c20dcf69715848c827eef16840540c45fe0d76fc1a61341c
|
4
|
+
data.tar.gz: 69caf5e66fdacee7e9b5a4c5271387e0823f6f10f90373b9cdd149966563ad3f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11a71582b7e0ed144cc0d3256dabc4c2e7f2f459c81459f2d809af16ddd02de0ee9ec9af45cdc6fbaae4d2c809857148b668e47186c0c110a1b708153f687373
|
7
|
+
data.tar.gz: c34d2b7773016ccd2328778d1d8b9a9be5cca14c403684b3870dfe47d3fe5988ae3acad1ec0bcb2453468304b4a329e16a35aa7f72efec48f64d9da1ca2fcf19
|
data/README.md
CHANGED
@@ -9,6 +9,9 @@ A gem to standardize json responses in Rails applications, highly inspired on [R
|
|
9
9
|
- [Usage](#usage)
|
10
10
|
- [Respondering json](#respondering-json)
|
11
11
|
- [Success and failure actions](#success-and-failure-actions)
|
12
|
+
- [Errors](#errors)
|
13
|
+
- [Message](#message)
|
14
|
+
- [Transform keys](#transform-keys)
|
12
15
|
- [Overriding response](#overriding-response)
|
13
16
|
- [Pagination](#pagination)
|
14
17
|
- [Contributing](#contributing)
|
@@ -141,6 +144,64 @@ The `message` key is different based on actions on informed model: create, updat
|
|
141
144
|
|
142
145
|
You can respond any type of data, but ActiveRecord/ActiveModel::Model and ActiveRecord::Relation has a special treatment as shown above
|
143
146
|
|
147
|
+
### Errors
|
148
|
+
To show errors of a model, by default will use the `errors.messages` method, but `MiniApi` adds an ability to `active_model_serializers` to create a error serializer
|
149
|
+
as a nested class in your serializer. Example:
|
150
|
+
```ruby
|
151
|
+
class UserSerializer < ActiveModel::Serializer
|
152
|
+
attributes :id, :first_name, :last_name
|
153
|
+
|
154
|
+
class Error < ActiveModel::Serializer
|
155
|
+
attributes :user
|
156
|
+
|
157
|
+
def user
|
158
|
+
{
|
159
|
+
first_name: object.errors[:first_name],
|
160
|
+
last_name: object.errors[:last_name],
|
161
|
+
}
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
```
|
166
|
+
The response will be like:
|
167
|
+
```json
|
168
|
+
{
|
169
|
+
"success": false,
|
170
|
+
"errors": {
|
171
|
+
"user": {
|
172
|
+
"first_name": "can't be blank",
|
173
|
+
"last_name": "can't be blank"
|
174
|
+
}
|
175
|
+
},
|
176
|
+
"message": "User could not be created."
|
177
|
+
}
|
178
|
+
```
|
179
|
+
You can create serializers for non `ActiveRecord` and add a nested `Error` class too
|
180
|
+
|
181
|
+
### Message
|
182
|
+
|
183
|
+
The `I18n` path for the key `message` is `mini_api.messages.actions`, the controller action name and the `notice` for success actions
|
184
|
+
or `alert` for failure actions. Example `mini_api.messages.actions.create.notice`
|
185
|
+
|
186
|
+
By default support the actions: `create`, `update` and `delete`, but you can add more actions to translate
|
187
|
+
|
188
|
+
You can add translation based on models, changing the `action` key for your model name. Example:
|
189
|
+
`mini_api.messages.model_name.create.alert`. With this, is more easy personalize messages
|
190
|
+
|
191
|
+
### Transform keys
|
192
|
+
|
193
|
+
It is possible to transform the keys of request and response. By default, will transform to `snake_case`, but the possible values are `snake_case`, `camel_lower` and `camel_case`
|
194
|
+
|
195
|
+
To change the transform operation, simply adds a initializer on initilizations folder with content:
|
196
|
+
```ruby
|
197
|
+
MiniApi::Config.configure do |config|
|
198
|
+
config.transform_params_keys_to = :snake_case
|
199
|
+
config.transform_response_keys_to = :camel_lower
|
200
|
+
end
|
201
|
+
```
|
202
|
+
The option `transform_params_keys_to` will transform request params.
|
203
|
+
The option `transform_response_keys_to` will transform responses.
|
204
|
+
|
144
205
|
## Overriding response
|
145
206
|
|
146
207
|
You can override the `status`, `message` and `sucess` keys simply informing values to `render_json`. Example:
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mini_api/config'
|
4
|
+
require 'mini_api/exceptions/case_transform_option_invalid'
|
5
|
+
|
6
|
+
module MiniApi
|
7
|
+
module CaseTransform
|
8
|
+
module_function
|
9
|
+
|
10
|
+
def transform(object, transform_to = :snake_case)
|
11
|
+
object.deep_transform_keys do |key|
|
12
|
+
case transform_to
|
13
|
+
when :camel_case
|
14
|
+
key.to_s.camelize
|
15
|
+
when :camel_lower
|
16
|
+
key.to_s.camelize(:lower)
|
17
|
+
when :snake_case
|
18
|
+
key.to_s.underscore
|
19
|
+
else
|
20
|
+
raise CaseTransformOptionInvalid, "option #{transform_to} is not supported."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def request_params_keys(params)
|
26
|
+
transform(params, Config.transform_params_keys_to)
|
27
|
+
end
|
28
|
+
|
29
|
+
def response_keys(response)
|
30
|
+
transform(response, Config.transform_response_keys_to)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MiniApi
|
4
|
+
class Config
|
5
|
+
include ActiveSupport::Configurable
|
6
|
+
|
7
|
+
# permitted values are: [:camel_case, :camel_lower, snake_case]
|
8
|
+
config_accessor :transform_params_keys_to, instance_accessor: false, default: :snake_case
|
9
|
+
config_accessor :transform_response_keys_to, instance_accessor: false, default: :snake_case
|
10
|
+
end
|
11
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'mini_api/case_transform'
|
4
|
+
|
3
5
|
module MiniApi
|
4
6
|
class DefaultResponder
|
5
7
|
def initialize(controller, resource, options = {})
|
@@ -11,14 +13,39 @@ module MiniApi
|
|
11
13
|
def respond
|
12
14
|
success = @options[:success] != false
|
13
15
|
|
16
|
+
data = transform_keys
|
17
|
+
|
18
|
+
body =
|
19
|
+
if success
|
20
|
+
{ data: data }
|
21
|
+
else
|
22
|
+
{ errors: data }
|
23
|
+
end
|
24
|
+
|
14
25
|
@controller.render(
|
15
26
|
json: {
|
16
27
|
success: success,
|
17
|
-
|
18
|
-
|
28
|
+
message: @options[:message] || nil,
|
29
|
+
**body
|
19
30
|
},
|
20
31
|
status: @options[:status] || :ok
|
21
32
|
)
|
22
33
|
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def transform_keys
|
38
|
+
return CaseTransform.response_keys(@resource) if @resource.is_a?(Hash)
|
39
|
+
|
40
|
+
return @resource unless @resource.is_a?(Array)
|
41
|
+
|
42
|
+
@resource.map do |item|
|
43
|
+
if item.is_a?(Hash)
|
44
|
+
CaseTransform.response_keys(item)
|
45
|
+
else
|
46
|
+
item
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
23
50
|
end
|
24
51
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'mini_api/serialization'
|
4
|
+
require 'mini_api/case_transform'
|
4
5
|
|
5
6
|
module MiniApi
|
6
7
|
# class to handle json render of ActiveRecord::Base instances and ActiveModel::Model's
|
@@ -21,7 +22,7 @@ module MiniApi
|
|
21
22
|
|
22
23
|
body =
|
23
24
|
if resource_has_errors?
|
24
|
-
|
25
|
+
errors.merge(body)
|
25
26
|
else
|
26
27
|
{ data: serialiable_body(@resource).as_json }.merge(body)
|
27
28
|
end
|
@@ -30,6 +31,8 @@ module MiniApi
|
|
30
31
|
# attribute when resource is an ActiveModel instance
|
31
32
|
body[:data] = body[:data].except('errors') if body[:data]&.key?('errors')
|
32
33
|
|
34
|
+
body = CaseTransform.response_keys(body)
|
35
|
+
|
33
36
|
@controller.render json: body, status: status_code
|
34
37
|
end
|
35
38
|
|
@@ -39,6 +42,14 @@ module MiniApi
|
|
39
42
|
!@resource.errors.empty?
|
40
43
|
end
|
41
44
|
|
45
|
+
def errors
|
46
|
+
error_serializer = get_error_serializer(@resource)
|
47
|
+
|
48
|
+
return { errors: @resource.errors.messages } unless error_serializer
|
49
|
+
|
50
|
+
{ errors: error_serializer.new(@resource).as_json }
|
51
|
+
end
|
52
|
+
|
42
53
|
def status_code
|
43
54
|
return @options[:status] if @options[:status].present?
|
44
55
|
|
@@ -54,12 +65,23 @@ module MiniApi
|
|
54
65
|
def default_message
|
55
66
|
kind = resource_has_errors? ? 'alert' : 'notice'
|
56
67
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
68
|
+
model_path = "mini_api.messages.#{@resource.model_name.i18n_key}"
|
69
|
+
|
70
|
+
if I18n.exists? model_path
|
71
|
+
I18n.t(
|
72
|
+
kind,
|
73
|
+
scope: "#{model_path}.#{@controller.action_name}",
|
74
|
+
resource_name: @resource.class.model_name.human,
|
75
|
+
default: ''
|
76
|
+
)
|
77
|
+
else
|
78
|
+
I18n.t(
|
79
|
+
kind,
|
80
|
+
scope: [:mini_api, :messages, :actions, @controller.action_name],
|
81
|
+
resource_name: @resource.class.model_name.human,
|
82
|
+
default: ''
|
83
|
+
)
|
84
|
+
end
|
63
85
|
end
|
64
86
|
|
65
87
|
def previously_new_record?
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'mini_api/exceptions/kaminari_not_installed'
|
4
4
|
require 'mini_api/serialization'
|
5
|
+
require 'mini_api/case_transform'
|
5
6
|
|
6
7
|
module MiniApi
|
7
8
|
class RelationResponder
|
@@ -16,6 +17,10 @@ module MiniApi
|
|
16
17
|
def respond
|
17
18
|
meta, collection = extract_meta_and_collection
|
18
19
|
|
20
|
+
meta = CaseTransform.response_keys(meta)
|
21
|
+
|
22
|
+
collection = transform_case(collection.as_json)
|
23
|
+
|
19
24
|
@controller.render json: {
|
20
25
|
success: @options[:success] || true,
|
21
26
|
data: collection,
|
@@ -40,6 +45,10 @@ module MiniApi
|
|
40
45
|
]
|
41
46
|
end
|
42
47
|
|
48
|
+
def transform_case(collection)
|
49
|
+
collection.map { |item| CaseTransform.response_keys(item) }
|
50
|
+
end
|
51
|
+
|
43
52
|
def transform_resource_to_collection
|
44
53
|
unless defined?(Kaminari)
|
45
54
|
raise KaminariNotInstalled, 'The Kaminari gem is not installed. Install to perform pagination operations'
|
data/lib/mini_api/version.rb
CHANGED
data/lib/mini_api.rb
CHANGED
@@ -2,9 +2,23 @@
|
|
2
2
|
|
3
3
|
require 'mini_api/railtie'
|
4
4
|
require 'mini_api/responder'
|
5
|
+
require 'mini_api/case_transform'
|
5
6
|
|
6
7
|
# Entrypoint module
|
7
8
|
module MiniApi
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
include CaseTransform
|
13
|
+
|
14
|
+
before_action :transform_params
|
15
|
+
|
16
|
+
def transform_params
|
17
|
+
self.params =
|
18
|
+
ActionController::Parameters.new(CaseTransform.request_params_keys(request.parameters))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
8
22
|
def render_json(resource, options = {})
|
9
23
|
responder = Responder.new(self, resource, options)
|
10
24
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mini_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Leon Cruz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-06-
|
11
|
+
date: 2023-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -35,7 +35,10 @@ files:
|
|
35
35
|
- README.md
|
36
36
|
- Rakefile
|
37
37
|
- lib/mini_api.rb
|
38
|
+
- lib/mini_api/case_transform.rb
|
39
|
+
- lib/mini_api/config.rb
|
38
40
|
- lib/mini_api/default_responder.rb
|
41
|
+
- lib/mini_api/exceptions/case_transform_option_invalid.rb
|
39
42
|
- lib/mini_api/exceptions/kaminari_not_installed.rb
|
40
43
|
- lib/mini_api/locales/en.yml
|
41
44
|
- lib/mini_api/model_responder.rb
|