rails_api_documentation 0.3.1 → 0.3.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 +4 -4
- data/README.md +58 -3
- data/app/views/rails_api_doc/api_docs/_request_api_table.slim +1 -1
- data/app/views/rails_api_doc/api_docs/_response_api_table.slim +1 -1
- data/app/views/shared/_table.slim +1 -1
- data/lib/rails_api_doc/controller/request/dsl.rb +32 -3
- data/lib/rails_api_doc/controller/request/factory.rb +4 -4
- data/lib/rails_api_doc/controller/request/param.rb +3 -3
- data/lib/rails_api_doc/controller/response/factory.rb +1 -12
- data/lib/rails_api_doc/controller/response/headers.rb +0 -1
- data/lib/rails_api_doc/controller/response/repository.rb +11 -1
- data/lib/rails_api_doc/controller/strong_params/dsl.rb +9 -4
- data/lib/rails_api_doc/controller/strong_params/permitted_params.rb +6 -4
- data/lib/rails_api_doc/model/attribute_merger.rb +34 -29
- data/lib/rails_api_doc/model/attribute_parser.rb +1 -0
- data/lib/rails_api_doc/version.rb +1 -1
- data/lib/rails_api_doc.rb +3 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a72e86cdcaefec61dd47079acd6df5eb7ad88762
|
4
|
+
data.tar.gz: dc2ee37bbed89765494a3b697ab337db746aaefb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a1d84265c02e6c7c588078cb27790bb1a231a6451aa35c3c24210b41a2ec62237deb611be3408346f66dbcd8e68fb6a44f8473194eedb77acc0f4e5e528a085
|
7
|
+
data.tar.gz: 43e6fb0376be3a10f0da24cf170bc42110b79869308e5d3b7ebaf19e59104b872e2c34365bc2647ba5e50ab6fb803e38115382579e704f56d4d6692153aeb1d7
|
data/README.md
CHANGED
@@ -22,7 +22,7 @@ Or install it yourself as:
|
|
22
22
|
+ displaying application api if used in one of correct ways
|
23
23
|

|
24
24
|
+ Integration with Rabl if it is bundled
|
25
|
-
+ ```
|
25
|
+
+ ```strong_params``` method that will filter incoming params for you
|
26
26
|
|
27
27
|
## Usage
|
28
28
|
|
@@ -56,7 +56,16 @@ To display api documentation on route '/api_doc' you need to:
|
|
56
56
|
parameter :comment, type: :string
|
57
57
|
end
|
58
58
|
end
|
59
|
-
parameter :test, type:
|
59
|
+
parameter :test, type: :string, required: true
|
60
|
+
|
61
|
+
parameter({
|
62
|
+
articles_attributes: { model: 'Article', type: :ary_object },
|
63
|
+
data_attributes: { model: 'Datum' },
|
64
|
+
comments_attributes: { model: 'Comment', type: :ary_object }
|
65
|
+
}, type: :object) do
|
66
|
+
parameter :id
|
67
|
+
parameter :name
|
68
|
+
end
|
60
69
|
|
61
70
|
end
|
62
71
|
```
|
@@ -75,7 +84,7 @@ To display api documentation on route '/api_doc' you need to:
|
|
75
84
|
|
76
85
|
# controller action
|
77
86
|
def create
|
78
|
-
Comment.create!(
|
87
|
+
Comment.create!(strong_params)
|
79
88
|
end
|
80
89
|
|
81
90
|
```
|
@@ -84,6 +93,52 @@ To display api documentation on route '/api_doc' you need to:
|
|
84
93
|
|
85
94
|
Comment will be created with: `Comment(body='Comment body', title='Comment title', age=nil)`
|
86
95
|
|
96
|
+
## Value
|
97
|
+
|
98
|
+
You can pass optional value argument to every parameter:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
parameter :val, type: :integer, value: -> (request_value) { 5 }
|
102
|
+
```
|
103
|
+
|
104
|
+
on every matching request value in this field will be overriden by value returned by proc.
|
105
|
+
|
106
|
+
value field expecting anything that will respond to `:call` and can accept one argument(param value from request)
|
107
|
+
|
108
|
+
you should expect that value passed can be `nil`
|
109
|
+
|
110
|
+
This can be used to force values on some fields, or modify values passed to request in some ways.
|
111
|
+
|
112
|
+
E.g. you want to force current_user_id on model creation instead of passing it from frontend.
|
113
|
+
|
114
|
+
## Enum
|
115
|
+
|
116
|
+
When you defined parameter type as `:enum` you can pass `enum:` option. This will filter parameter by values provided.
|
117
|
+
|
118
|
+
## Group common blocks
|
119
|
+
|
120
|
+
You can define parameters that have common fields this way:
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
parameter({
|
124
|
+
articles_attributes: { model: 'Article', type: :ary_object },
|
125
|
+
data_attributes: { model: 'Datum' },
|
126
|
+
comments_attributes: { model: 'Comment', type: :ary_object }
|
127
|
+
}, type: :object) do
|
128
|
+
parameter :id
|
129
|
+
parameter :name
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
Pass common values as last optional arguments and uniq definitions as hash value.
|
134
|
+
All nesting parameters are applied to elements in blocks.
|
135
|
+
|
136
|
+
Something with same type can be defined like this:
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
parameter :name, :desc, type: :string
|
140
|
+
```
|
141
|
+
|
87
142
|
## Types
|
88
143
|
|
89
144
|
Parameter type may be one of these:
|
@@ -2,4 +2,4 @@
|
|
2
2
|
|
3
3
|
div[id="#{ctrl}.request" style="--row-count: #{request_headers.length}"]
|
4
4
|
|
5
|
-
= render 'shared/table', model: ctrl, rows: repo[ctrl], headers: request_headers, nesting: [], params: { api_type: :request }
|
5
|
+
= render 'shared/table', model: ctrl, rows: repo[ctrl.name], headers: request_headers, nesting: [], params: { api_type: :request }
|
@@ -11,6 +11,6 @@ div.response-table[id="#{ctrl}.response" style="--row-count: #{response_headers
|
|
11
11
|
div.request-action-title
|
12
12
|
= render 'shared/title', locals: { blue_title: route[:method], yellow_title: route[:url]}
|
13
13
|
|
14
|
-
- if rows = repo.
|
14
|
+
- if rows = repo.load_attrs(ctrl, action)
|
15
15
|
|
16
16
|
= render 'shared/table', model: ctrl, rows: rows, headers: response_headers, nesting: [], params: { api_action: action, api_type: :response }
|
@@ -29,7 +29,7 @@ div.flex-table
|
|
29
29
|
- if index.zero?
|
30
30
|
span.ico ✏
|
31
31
|
/ = submit_tag ,name: 'destroy', class: 'ico destroy'
|
32
|
-
= link_to '❌' , api_doc_url(construct_destroy_param(row_values, params, nesting)), method: :delete,
|
32
|
+
= link_to '❌' , api_doc_url(construct_destroy_param(row_values, params, nesting)), method: :delete,data: { confirm: 'Are you sure?' }, class: 'destroy ico'
|
33
33
|
span.exit.ico ❌
|
34
34
|
= submit_tag '✔'
|
35
35
|
|
@@ -5,19 +5,48 @@ module RailsApiDoc
|
|
5
5
|
module Request
|
6
6
|
module DSL
|
7
7
|
|
8
|
+
#
|
8
9
|
# Use parameter in controller to define REQUEST parameter.
|
9
10
|
# Adds it to repository: RailsApiDoc::Controller::Request::Repository
|
10
|
-
|
11
|
+
# Params can be defined in several ways:
|
12
|
+
# 1. parameter :name, type: :string
|
13
|
+
#
|
14
|
+
# 2. parameter {
|
15
|
+
# dose_form_attributes: { model: 'Rxnorm::RxDoseForm' },
|
16
|
+
# input_method_attributes: { model: 'TreatmentInfo::InputMethod' },
|
17
|
+
# input_condition_attributes: { model: 'Drugs::InputCondition' },
|
18
|
+
# input_duration_attributes: { model: 'Drugs::InputDuration' }
|
19
|
+
# }, type: :object do
|
20
|
+
# parameter :id
|
21
|
+
# parameter :name
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# 3. parameter :name, :code, type: :string
|
25
|
+
#
|
26
|
+
def parameter(*arguments, &block)
|
27
|
+
options = arguments.extract_options!
|
28
|
+
|
11
29
|
raise ArgumentError, 'Parameter already defined.' if repo.key?(name)
|
12
30
|
|
13
31
|
validate_options(options, block_given?)
|
14
32
|
|
15
|
-
|
33
|
+
arguments.each do |param|
|
34
|
+
# 2)
|
35
|
+
if param.is_a?(Hash)
|
36
|
+
param.each do |param_name, additional_options|
|
37
|
+
_options = options.merge(additional_options)
|
38
|
+
|
39
|
+
define_parameter(param_name, _options, &block)
|
40
|
+
end
|
41
|
+
else # 1), 3)
|
42
|
+
define_parameter(param, options, &block)
|
43
|
+
end
|
44
|
+
end
|
16
45
|
end
|
17
46
|
|
18
47
|
private
|
19
48
|
|
20
|
-
def validate_options(options,
|
49
|
+
def validate_options(options, _block_given)
|
21
50
|
options.assert_valid_keys(RailsApiDoc::Controller::Param::VALID_KEYS)
|
22
51
|
|
23
52
|
RailsApiDoc::Controller::Request::Param.valid_type?(options[:type])
|
@@ -4,11 +4,11 @@ class RailsApiDoc::Controller::Request::Factory
|
|
4
4
|
class << self
|
5
5
|
|
6
6
|
def repo
|
7
|
-
|
7
|
+
repo = RailsApiDoc::Controller::Request::Repository.new
|
8
8
|
|
9
|
-
|
9
|
+
repo.repo = merge_attributes_from_model repo.repo
|
10
10
|
|
11
|
-
|
11
|
+
repo
|
12
12
|
end
|
13
13
|
|
14
14
|
def registered_controllers
|
@@ -21,7 +21,7 @@ class RailsApiDoc::Controller::Request::Factory
|
|
21
21
|
# do not mutate attributes
|
22
22
|
#
|
23
23
|
def merge_attributes_from_model(attributes)
|
24
|
-
RailsApiDoc::Model::AttributeMerger.new(attributes
|
24
|
+
RailsApiDoc::Model::AttributeMerger.new(attributes, 'request').call
|
25
25
|
end
|
26
26
|
|
27
27
|
end
|
@@ -8,11 +8,7 @@ class RailsApiDoc::Controller::Response::Factory
|
|
8
8
|
# TODO: add more options later depending on app settings
|
9
9
|
# TODO: rename to :load_repo
|
10
10
|
def repo
|
11
|
-
|
12
|
-
|
13
|
-
attributes = merge_attributes_from_model attributes
|
14
|
-
|
15
|
-
attributes
|
11
|
+
RailsApiDoc::Controller::Response::Repository.new(repository.repo)
|
16
12
|
end
|
17
13
|
|
18
14
|
def controllers
|
@@ -25,13 +21,6 @@ class RailsApiDoc::Controller::Response::Factory
|
|
25
21
|
@repo ||= ::RailsApiDoc::Controller::Response::Rabl.new(controllers)
|
26
22
|
end
|
27
23
|
|
28
|
-
#
|
29
|
-
# do not mutate attributes
|
30
|
-
#
|
31
|
-
def merge_attributes_from_model(attributes)
|
32
|
-
RailsApiDoc::Model::AttributeMerger.new(attributes).call(api_type: 'response')
|
33
|
-
end
|
34
|
-
|
35
24
|
end
|
36
25
|
|
37
26
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# author: Vadim Shaveiko <@vshaveyko>
|
1
3
|
# :nodoc:
|
2
4
|
class RailsApiDoc::Controller::Response::Repository
|
3
5
|
|
@@ -5,7 +7,15 @@ class RailsApiDoc::Controller::Response::Repository
|
|
5
7
|
include RailsApiDoc::Controller::Response::Headers
|
6
8
|
|
7
9
|
def initialize(repo)
|
8
|
-
@repo = repo.clone.transform_values
|
10
|
+
@repo = repo.clone.transform_values(&:deep_dup)
|
11
|
+
end
|
12
|
+
|
13
|
+
def load_attrs(ctrl, action)
|
14
|
+
at = load_template(ctrl, action)&.nodes || {}
|
15
|
+
|
16
|
+
at = RailsApiDoc::Model::AttributeMerger.new(at, 'response').merge_action(action: action, ctrl: ctrl)
|
17
|
+
|
18
|
+
at
|
9
19
|
end
|
10
20
|
|
11
21
|
def load_template(ctrl, action)
|
@@ -1,14 +1,19 @@
|
|
1
|
-
# :
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# author: Vadim Shaveiko <@vshaveyko>
|
2
3
|
module RailsApiDoc
|
3
4
|
module Controller
|
4
5
|
module ResourceParams
|
5
|
-
module DSL
|
6
|
+
module DSL # :nodoc:
|
6
7
|
|
7
8
|
include RailsApiDoc::Controller::ResourceParams::PermittedParams # implements params_to_permit
|
8
9
|
|
9
|
-
def
|
10
|
+
def strong_params(pars = params)
|
11
|
+
#
|
10
12
|
# accepted_params for permit
|
11
|
-
|
13
|
+
#
|
14
|
+
permitted = params_to_permit(pars)
|
15
|
+
|
16
|
+
pars.permit(permitted)
|
12
17
|
end
|
13
18
|
|
14
19
|
end
|
@@ -7,8 +7,8 @@ module RailsApiDoc
|
|
7
7
|
|
8
8
|
private
|
9
9
|
|
10
|
-
def params_to_permit
|
11
|
-
_next_nesting_level(
|
10
|
+
def params_to_permit(pars = params)
|
11
|
+
_next_nesting_level(pars, param_data: _permitted_params)
|
12
12
|
end
|
13
13
|
|
14
14
|
def _permitted_params
|
@@ -32,7 +32,6 @@ module RailsApiDoc
|
|
32
32
|
level_accepted_params
|
33
33
|
end
|
34
34
|
|
35
|
-
|
36
35
|
#
|
37
36
|
# loop through current level of params and add to permit level if all requirements are met
|
38
37
|
#
|
@@ -47,6 +46,10 @@ module RailsApiDoc
|
|
47
46
|
#
|
48
47
|
def loop_params(params, level_permitted_params, accepted_params)
|
49
48
|
level_permitted_params.each do |param_name, api_param_data|
|
49
|
+
if api_param_data.value&.respond_to?(:call)
|
50
|
+
params[param_name] = api_param_data.value.call(params[param_name])
|
51
|
+
end
|
52
|
+
|
50
53
|
controller_param = params[param_name]
|
51
54
|
|
52
55
|
_check_required(param_name, controller_param, api_param_data) # raise if required and no value
|
@@ -63,7 +66,6 @@ module RailsApiDoc
|
|
63
66
|
param_data: api_param_data.nested,
|
64
67
|
current_accepted_params: accepted_params,
|
65
68
|
param_name: param_name)
|
66
|
-
|
67
69
|
end
|
68
70
|
elsif api_param_data.nested? # value should be nested object
|
69
71
|
_next_nesting_level(controller_param,
|
@@ -6,53 +6,58 @@ class RailsApiDoc::Model::AttributeMerger
|
|
6
6
|
MODEL = RailsApiDoc::ApiDatum
|
7
7
|
MERGABLE_FIELDS = [:type, :desc, :action_type].freeze
|
8
8
|
|
9
|
+
@@data = MODEL.all
|
10
|
+
|
9
11
|
#
|
10
12
|
# do not mutate attributes
|
11
13
|
#
|
12
14
|
# please - impossible
|
13
15
|
#
|
14
|
-
def initialize(attributes)
|
15
|
-
@attrs = attributes
|
16
|
+
def initialize(attributes, api_type)
|
17
|
+
@attrs = attributes.stringify_keys
|
18
|
+
@api_type = api_type
|
16
19
|
end
|
17
20
|
|
18
|
-
def
|
19
|
-
@api_type
|
21
|
+
def merge_action(action:, ctrl:)
|
22
|
+
merge_data = @@data.select { |d| d.api_type == @api_type && d.api_action == action.to_s && d.nesting.first == ctrl.name }
|
20
23
|
|
21
|
-
|
22
|
-
_add_nested_param(param)
|
24
|
+
merge_data.each do |param|
|
25
|
+
_add_nested_param(param, param.nesting[1..-1], @attrs)
|
23
26
|
end
|
24
27
|
|
25
28
|
@attrs
|
26
29
|
end
|
27
30
|
|
28
|
-
|
31
|
+
def call
|
32
|
+
api_params = @@data.select { |d| d.api_type == @api_type }.each do |param|
|
33
|
+
#
|
34
|
+
# nesting should be present for parameter to appear
|
35
|
+
#
|
36
|
+
next unless param.name && param.nesting.present?
|
29
37
|
|
30
|
-
|
31
|
-
# nesting should be present for parameter to appear
|
32
|
-
return if param.nesting.blank?
|
38
|
+
attrs, nesting, name = _parse_settings(param)
|
33
39
|
|
34
|
-
|
40
|
+
_add_nested_param(param, nesting, attrs)
|
41
|
+
end
|
35
42
|
|
36
|
-
|
43
|
+
@attrs
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
37
47
|
|
38
|
-
|
48
|
+
def _add_nested_param(param, nesting, attrs)
|
49
|
+
ctrl_param = _find_param(nesting, param.name, attrs)
|
39
50
|
|
40
51
|
ctrl_param.param = param
|
41
52
|
# _merge_data_to_param(ctrl_param, param)
|
42
53
|
end
|
43
54
|
|
44
55
|
def _parse_settings(param)
|
45
|
-
ctrl = param.nesting[0]
|
56
|
+
ctrl = param.nesting[0]
|
46
57
|
nesting = param.nesting[1..-1]
|
47
58
|
name = param.name&.to_sym
|
48
59
|
attrs = @attrs[ctrl]
|
49
60
|
|
50
|
-
#
|
51
|
-
# making exception
|
52
|
-
# until request parameters are not split by actions
|
53
|
-
#
|
54
|
-
attrs = attrs[param.api_action] if @api_type == 'response'
|
55
|
-
|
56
61
|
[attrs, nesting, name]
|
57
62
|
end
|
58
63
|
|
@@ -82,18 +87,18 @@ class RailsApiDoc::Model::AttributeMerger
|
|
82
87
|
end
|
83
88
|
end
|
84
89
|
|
85
|
-
def _find_param(
|
86
|
-
|
87
|
-
|
90
|
+
def _find_param(nest, name, attrs)
|
91
|
+
nest.each do |model|
|
92
|
+
#
|
93
|
+
# model on different fields because of wrong nesting sturcture for request
|
94
|
+
# TODO: fix this later
|
95
|
+
#
|
96
|
+
nested_attrs = attrs.detect { |k, v| v.nested? && (v.model == model || k.to_s == model) }
|
88
97
|
|
89
98
|
attrs = nested_attrs ? nested_attrs : _define_nesting_level(attrs, name, model)
|
90
99
|
end
|
91
100
|
|
92
|
-
|
93
|
-
attrs[name]
|
94
|
-
else
|
95
|
-
attrs[name] = _init_param_for_api_type(name)
|
96
|
-
end
|
101
|
+
attrs[name] ||= _init_param_for_api_type(name, {})
|
97
102
|
end
|
98
103
|
|
99
104
|
def _define_nesting_level(attrs, name, model)
|
@@ -123,7 +128,7 @@ class RailsApiDoc::Model::AttributeMerger
|
|
123
128
|
if @api_type == 'request'
|
124
129
|
RailsApiDoc::Controller::Request::Param.new(name, options, is_new: true)
|
125
130
|
elsif @api_type == 'response'
|
126
|
-
RailsApiDoc::Controller::Response::Param.new(name, name, options[:nested], options[:model],
|
131
|
+
RailsApiDoc::Controller::Response::Param.new(name, name, options[:nested], options[:model], nil, options[:type], is_new: true)
|
127
132
|
end
|
128
133
|
end
|
129
134
|
|
data/lib/rails_api_doc.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
# author: Vadim Shaveiko <@vshaveyko>
|
2
2
|
# frozen_string_literal: true
|
3
3
|
module RailsApiDoc
|
4
|
-
|
4
|
+
|
5
|
+
NESTED_TYPES = [:ary_object, :object, :json].freeze
|
5
6
|
|
6
|
-
STRAIGHT_TYPES = [:bool, :string, :integer, :array, :datetime, :enum].freeze
|
7
|
+
STRAIGHT_TYPES = [:bool, :string, :integer, :array, :datetime, :enum, :model].freeze
|
7
8
|
|
8
9
|
ACCEPTED_TYPES = (NESTED_TYPES + STRAIGHT_TYPES).freeze
|
9
10
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_api_documentation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- vs
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|