jsonapi_parameters 0.0.2
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +80 -0
- data/Rakefile +27 -0
- data/lib/jsonapi_parameters.rb +4 -0
- data/lib/jsonapi_parameters/core_ext.rb +1 -0
- data/lib/jsonapi_parameters/core_ext/action_controller/parameters.rb +9 -0
- data/lib/jsonapi_parameters/parameters.rb +4 -0
- data/lib/jsonapi_parameters/translator.rb +101 -0
- data/lib/jsonapi_parameters/version.rb +3 -0
- metadata +208 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6555a67a071e9f66fe99064c4f0db8e102b846506996724885ee020a7c433885
|
4
|
+
data.tar.gz: 49c73fb6120db15c1b92c17e1d5353d38b9e8da51d3baaad77fe4274d06db7e2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: '093733d461f89c9d566b70576bec51132699b3bb6a883fc7a132795a829aea8faeb0831cb18002c122df82d826becedd65e251291954ea1972b8eeeca9a184ac'
|
7
|
+
data.tar.gz: d31cf2eccb58666e87eefb06c3a7537d83bfea06858850aa8ac093dbdf7ec52e782bf904c2f43306a14beef2dfa6931444dddc52e1cd2854e9cae502f6f6d75c
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2019 marahin
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# JsonApi::Parameters
|
2
|
+
Simple JSON:API compliant parameters translator.
|
3
|
+
|
4
|
+
#### The problem
|
5
|
+
|
6
|
+
JSON:API standard specifies not only responses (that can be handled nicely, using gems like [fast_jsonapi from Netflix](https://github.com/Netflix/fast_jsonapi)), but also the request structure.
|
7
|
+
|
8
|
+
#### The solution
|
9
|
+
|
10
|
+
As we couldn't find any gem that would make it easier in Rails to use these structures, we decided to create something that will work for us - a translator that transforms JSON:API compliant request parameter strucure into a Railsy structure.
|
11
|
+
|
12
|
+
## Usage
|
13
|
+
|
14
|
+
### Installation
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
gem 'jsonapi_parameters'
|
19
|
+
```
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
|
23
|
+
```bash
|
24
|
+
$ bundle
|
25
|
+
```
|
26
|
+
|
27
|
+
Or install it yourself as:
|
28
|
+
|
29
|
+
```bash
|
30
|
+
$ gem install jsonapi_parameters
|
31
|
+
```
|
32
|
+
|
33
|
+
### Rails
|
34
|
+
|
35
|
+
Usually your strong parameters in controller are invoked this way:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
def create
|
39
|
+
model = Model.new(create_params)
|
40
|
+
|
41
|
+
if model.save
|
42
|
+
...
|
43
|
+
else
|
44
|
+
head 500
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def create_params
|
51
|
+
params.require(:model).permit(:name)
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
With jsonapi_parameters, the difference is just the params:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
def create_params
|
59
|
+
params.to_jsonapi.require(:model).permit(:name)
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
### Plain Ruby / outside Rails
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
|
67
|
+
params = { # JSON:API compliant parameters here
|
68
|
+
# ...
|
69
|
+
}
|
70
|
+
|
71
|
+
class Translator
|
72
|
+
include JsonApi::Parameters
|
73
|
+
end
|
74
|
+
translator = Translator.new
|
75
|
+
|
76
|
+
translator.jsonapify(params)
|
77
|
+
```
|
78
|
+
|
79
|
+
## License
|
80
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'JsonApiParameters'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'bundler/gem_tasks'
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
|
21
|
+
Rake::TestTask.new(:test) do |t|
|
22
|
+
t.libs << 'test'
|
23
|
+
t.pattern = 'test/**/*_test.rb'
|
24
|
+
t.verbose = false
|
25
|
+
end
|
26
|
+
|
27
|
+
task default: :test
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'core_ext/action_controller/parameters'
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module JsonApi::Parameters
|
2
|
+
def jsonapify(params)
|
3
|
+
jsonapi_translate(params)
|
4
|
+
end
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def jsonapi_translate(params)
|
9
|
+
params = params.to_unsafe_h if params.is_a?(ActionController::Parameters)
|
10
|
+
|
11
|
+
return params if params.nil? || params.empty?
|
12
|
+
|
13
|
+
@jsonapi_unsafe_hash = params.deep_symbolize_keys
|
14
|
+
|
15
|
+
formed_parameters
|
16
|
+
end
|
17
|
+
|
18
|
+
def formed_parameters
|
19
|
+
@formed_parameters ||= {}.tap do |param|
|
20
|
+
param[jsonapi_main_key.to_sym] = jsonapi_main_body
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def jsonapi_main_key
|
25
|
+
@jsonapi_unsafe_hash.dig(:data, :type)&.singularize || ''
|
26
|
+
end
|
27
|
+
|
28
|
+
def jsonapi_main_body
|
29
|
+
jsonapi_unsafe_params.tap do |param|
|
30
|
+
jsonapi_relationships.each do |relationship_key, relationship_value|
|
31
|
+
key, val = case relationship_value
|
32
|
+
when Array
|
33
|
+
handle_to_many_relation(relationship_key, relationship_value)
|
34
|
+
when Hash
|
35
|
+
handle_to_one_relation(relationship_key, relationship_value)
|
36
|
+
else
|
37
|
+
raise jsonapi_not_implemented_err
|
38
|
+
end
|
39
|
+
param[key] = val
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def jsonapi_unsafe_params
|
45
|
+
@jsonapi_unsafe_params ||= @jsonapi_unsafe_hash.dig(:data, :attributes) || {}
|
46
|
+
end
|
47
|
+
|
48
|
+
def jsonapi_included
|
49
|
+
@jsonapi_included ||= @jsonapi_unsafe_hash[:included] || []
|
50
|
+
end
|
51
|
+
|
52
|
+
def jsonapi_relationships
|
53
|
+
@jsonapi_relationships ||= @jsonapi_unsafe_hash.dig(:data, :relationships) || []
|
54
|
+
end
|
55
|
+
|
56
|
+
def handle_to_many_relation(relationship_key, relationship_value)
|
57
|
+
key = "#{relationship_key.to_s.pluralize}_attributes".to_sym
|
58
|
+
|
59
|
+
val = relationship_value.map do |relationship_value|
|
60
|
+
related_id = relationship_value.dig(:data, :id)
|
61
|
+
related_type = relationship_value.dig(:data, :type)
|
62
|
+
|
63
|
+
included_object = find_included_object(
|
64
|
+
related_id: related_id, related_type: related_type
|
65
|
+
) || {}
|
66
|
+
|
67
|
+
included_object.delete(:type)
|
68
|
+
|
69
|
+
included_object[:attributes].merge(id: related_id)
|
70
|
+
end
|
71
|
+
|
72
|
+
[key, val]
|
73
|
+
end
|
74
|
+
|
75
|
+
def handle_to_one_relation(relationship_key, relationship_value)
|
76
|
+
related_id = relationship_value.dig(:data, :id)
|
77
|
+
related_type = relationship_key.to_s
|
78
|
+
|
79
|
+
included_object = find_included_object(
|
80
|
+
related_id: related_id, related_type: related_type
|
81
|
+
)
|
82
|
+
|
83
|
+
return ["#{related_type.singularize}_id".to_sym, related_id] if included_object.nil?
|
84
|
+
|
85
|
+
included_object.delete(:type)
|
86
|
+
["#{related_type.singularize}_attributes".to_sym, included_object]
|
87
|
+
end
|
88
|
+
|
89
|
+
def find_included_object(related_id:, related_type:)
|
90
|
+
jsonapi_included.find do |included_object_enum|
|
91
|
+
included_object_enum[:id] &&
|
92
|
+
included_object_enum[:id] == related_id &&
|
93
|
+
included_object_enum[:type] &&
|
94
|
+
included_object_enum[:type] == related_type
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def jsonapi_not_implemented_err
|
99
|
+
NotImplementedError.new('relationship member must either be an Array or a Hash')
|
100
|
+
end
|
101
|
+
end
|
metadata
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jsonapi_parameters
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- marahin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-01-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.2.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.2.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.3.13
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.3.13
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.8.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.8.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.8.1
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.8.1
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.12.2
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.12.2
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.62.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.62.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop-rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 1.31.0
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 1.31.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: bundler-audit
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.6.0
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.6.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: fast_jsonapi
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '1.5'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '1.5'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: factory_bot
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 4.11.1
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 4.11.1
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: faker
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 1.9.1
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 1.9.1
|
167
|
+
description: JsonApi::Parameters allows you to easily translate JSON:API compliant
|
168
|
+
parameters to a structure expected by Rails.
|
169
|
+
email:
|
170
|
+
- me@marahin.pl
|
171
|
+
executables: []
|
172
|
+
extensions: []
|
173
|
+
extra_rdoc_files: []
|
174
|
+
files:
|
175
|
+
- MIT-LICENSE
|
176
|
+
- README.md
|
177
|
+
- Rakefile
|
178
|
+
- lib/jsonapi_parameters.rb
|
179
|
+
- lib/jsonapi_parameters/core_ext.rb
|
180
|
+
- lib/jsonapi_parameters/core_ext/action_controller/parameters.rb
|
181
|
+
- lib/jsonapi_parameters/parameters.rb
|
182
|
+
- lib/jsonapi_parameters/translator.rb
|
183
|
+
- lib/jsonapi_parameters/version.rb
|
184
|
+
homepage: https://github.com/visualitypl/jsonapi_parameters
|
185
|
+
licenses:
|
186
|
+
- MIT
|
187
|
+
metadata: {}
|
188
|
+
post_install_message:
|
189
|
+
rdoc_options: []
|
190
|
+
require_paths:
|
191
|
+
- lib
|
192
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
193
|
+
requirements:
|
194
|
+
- - ">="
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: 2.3.0
|
197
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
requirements: []
|
203
|
+
rubyforge_project:
|
204
|
+
rubygems_version: 2.7.3
|
205
|
+
signing_key:
|
206
|
+
specification_version: 4
|
207
|
+
summary: Translator for JSON:API compliant parameters
|
208
|
+
test_files: []
|