sober_swag 0.19.0 → 0.20.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/.github/workflows/lint.yml +1 -1
- data/.github/workflows/ruby.yml +1 -1
- data/.gitignore +2 -0
- data/.rubocop.yml +5 -1
- data/.yardopts +7 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +8 -0
- data/README.md +1 -1
- data/docs/serializers.md +3 -0
- data/example/Gemfile +1 -1
- data/example/config/environments/production.rb +1 -1
- data/lib/sober_swag.rb +6 -1
- data/lib/sober_swag/compiler.rb +29 -3
- data/lib/sober_swag/compiler/path.rb +42 -3
- data/lib/sober_swag/compiler/paths.rb +20 -0
- data/lib/sober_swag/compiler/primitive.rb +17 -0
- data/lib/sober_swag/compiler/type.rb +105 -22
- data/lib/sober_swag/controller.rb +39 -12
- data/lib/sober_swag/controller/route.rb +103 -20
- data/lib/sober_swag/input_object.rb +90 -7
- data/lib/sober_swag/nodes/array.rb +19 -0
- data/lib/sober_swag/nodes/attribute.rb +45 -4
- data/lib/sober_swag/nodes/base.rb +27 -7
- data/lib/sober_swag/nodes/binary.rb +30 -13
- data/lib/sober_swag/nodes/enum.rb +16 -1
- data/lib/sober_swag/nodes/list.rb +20 -0
- data/lib/sober_swag/nodes/nullable_primitive.rb +3 -0
- data/lib/sober_swag/nodes/object.rb +4 -1
- data/lib/sober_swag/nodes/one_of.rb +11 -3
- data/lib/sober_swag/nodes/primitive.rb +34 -2
- data/lib/sober_swag/nodes/sum.rb +8 -0
- data/lib/sober_swag/output_object.rb +35 -4
- data/lib/sober_swag/output_object/definition.rb +31 -1
- data/lib/sober_swag/output_object/field.rb +31 -11
- data/lib/sober_swag/output_object/field_syntax.rb +19 -3
- data/lib/sober_swag/output_object/view.rb +46 -1
- data/lib/sober_swag/parser.rb +7 -1
- data/lib/sober_swag/serializer/array.rb +27 -3
- data/lib/sober_swag/serializer/base.rb +75 -25
- data/lib/sober_swag/serializer/conditional.rb +33 -1
- data/lib/sober_swag/serializer/field_list.rb +18 -2
- data/lib/sober_swag/serializer/mapped.rb +10 -1
- data/lib/sober_swag/serializer/optional.rb +18 -1
- data/lib/sober_swag/serializer/primitive.rb +3 -0
- data/lib/sober_swag/server.rb +5 -1
- data/lib/sober_swag/type/named.rb +14 -0
- data/lib/sober_swag/types/comma_array.rb +4 -0
- data/lib/sober_swag/version.rb +1 -1
- metadata +3 -2
@@ -1,45 +1,95 @@
|
|
1
1
|
module SoberSwag
|
2
2
|
class Compiler
|
3
3
|
##
|
4
|
-
# A compiler for
|
5
|
-
#
|
4
|
+
# A compiler for swagger-able types.
|
5
|
+
#
|
6
|
+
# This class turns Swagger-able types into a *schema*.
|
7
|
+
# This Schema may be:
|
8
|
+
# - a [schema object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#schemaObject) with {#object_schema}
|
9
|
+
# - a [path schema](https://swagger.io/docs/specification/describing-parameters/#path-parameters) with {#path_schema}
|
10
|
+
# - a [query schema](https://swagger.io/docs/specification/describing-parameters/#query-parameters) with {#query_schema}
|
11
|
+
#
|
12
|
+
# As such, it compiles all types to all applicable schemas.
|
13
|
+
#
|
14
|
+
# While this class compiles *one* type at a time, it *keeps track* of the other types needed to describe this schema.
|
15
|
+
# It stores these types in a set, available at {#found_types}.
|
16
|
+
#
|
17
|
+
# For example, with a schema like:
|
18
|
+
#
|
19
|
+
# ```ruby
|
20
|
+
# class Bar < SoberSwag::InputObject
|
21
|
+
# attribute :baz, primitive(:String)
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# class Foo < SoberSwag::InputObject
|
25
|
+
# attribute :bar, Bar
|
26
|
+
# end
|
27
|
+
# ```
|
28
|
+
#
|
29
|
+
# If you compile `Foo` with this class, {#found_types} will include `Bar`.
|
30
|
+
#
|
6
31
|
class Type # rubocop:disable Metrics/ClassLength
|
32
|
+
##
|
33
|
+
# An error raised when a type is too complicated for a given schema.
|
34
|
+
# This may be due to containing too many layers of nesting.
|
7
35
|
class TooComplicatedError < ::SoberSwag::Compiler::Error; end
|
36
|
+
##
|
37
|
+
# An error raised when a type is too complicated to transform into a *path* schema.
|
8
38
|
class TooComplicatedForPathError < TooComplicatedError; end
|
39
|
+
##
|
40
|
+
# An error raised when a type is too complicated to transform into a *query* schema.
|
9
41
|
class TooComplicatedForQueryError < TooComplicatedError; end
|
10
42
|
|
43
|
+
##
|
44
|
+
# A list of acceptable keys to use as metadata for an object schema.
|
45
|
+
# All other metadata keys defined on a type with {SoberSwag::InputObject.meta} will be ignored.
|
46
|
+
#
|
47
|
+
# @return [Array<Symbol>] valid keys.
|
11
48
|
METADATA_KEYS = %i[description deprecated].freeze
|
12
49
|
|
50
|
+
##
|
51
|
+
# Create a new compiler for a swagger-able type.
|
52
|
+
# @param type [Class] the type to compile
|
13
53
|
def initialize(type)
|
14
54
|
@type = type
|
15
55
|
end
|
16
56
|
|
57
|
+
##
|
58
|
+
# @return [Class] the type we are compiling.
|
17
59
|
attr_reader :type
|
18
60
|
|
19
61
|
##
|
20
62
|
# Is this type standalone, IE, worth serializing on its own
|
21
63
|
# in the schemas section of our schema?
|
64
|
+
# @return [true,false]
|
22
65
|
def standalone?
|
23
66
|
type.is_a?(Class)
|
24
67
|
end
|
25
68
|
|
69
|
+
##
|
70
|
+
# Get back the [schema object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#schemaObject)
|
71
|
+
# for the type described.
|
72
|
+
#
|
73
|
+
# @return [Hash]
|
26
74
|
def object_schema
|
27
75
|
@object_schema ||=
|
28
76
|
make_object_schema
|
29
77
|
end
|
30
78
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
}.reject { |_, v| v.nil? }
|
37
|
-
end
|
38
|
-
|
79
|
+
##
|
80
|
+
# Give a "stub type" for this schema.
|
81
|
+
# This is suitable to use as the schema for attributes of other schemas.
|
82
|
+
# Almost always generates a ref object.
|
83
|
+
# @return [Hash] the OpenAPI V3 schema stub
|
39
84
|
def schema_stub
|
40
85
|
@schema_stub ||= generate_schema_stub
|
41
86
|
end
|
42
87
|
|
88
|
+
##
|
89
|
+
# The schema for this type when it is path of the path.
|
90
|
+
#
|
91
|
+
# @raise [TooComplicatedForPathError] when the compiled type is too complicated to use in a path
|
92
|
+
# @return [Hash] a [path parameters hash](https://swagger.io/docs/specification/describing-parameters/#path-parameters) for this type.
|
43
93
|
def path_schema
|
44
94
|
path_schema_stub.map do |e|
|
45
95
|
ensure_uncomplicated(e[:name], e[:schema])
|
@@ -51,16 +101,30 @@ module SoberSwag
|
|
51
101
|
|
52
102
|
DEFAULT_QUERY_SCHEMA_ATTRS = { in: :query, style: :deepObject, explode: true }.freeze
|
53
103
|
|
104
|
+
##
|
105
|
+
# The schema for this type when it is part of the query.
|
106
|
+
# @raise [TooComplicatedForQueryError] when this type is too complicated to use in a query schema
|
107
|
+
# @return [Hash] a [query parameters hash](https://swagger.io/docs/specification/describing-parameters/#query-parameters) for this type.
|
54
108
|
def query_schema
|
55
109
|
path_schema_stub.map { |e| DEFAULT_QUERY_SCHEMA_ATTRS.merge(e) }
|
56
110
|
rescue TooComplicatedError => e
|
57
111
|
raise TooComplicatedForQueryError, e.message
|
58
112
|
end
|
59
113
|
|
114
|
+
##
|
115
|
+
# Get the name of this type if it is to be used in a `$ref` key.
|
116
|
+
# This is useful if we are going to use this type compiler to compile an *attribute* of another object.
|
117
|
+
#
|
118
|
+
# @return [String] a reference specifier for this type
|
60
119
|
def ref_name
|
61
120
|
SoberSwag::Compiler::Primitive.new(type).ref_name
|
62
121
|
end
|
63
122
|
|
123
|
+
##
|
124
|
+
# Get a set of all other types needed to compile this type.
|
125
|
+
# This set will *not* include the type being compiled.
|
126
|
+
#
|
127
|
+
# @return [Set<Class>]
|
64
128
|
def found_types
|
65
129
|
@found_types ||=
|
66
130
|
begin
|
@@ -69,32 +133,51 @@ module SoberSwag
|
|
69
133
|
end
|
70
134
|
end
|
71
135
|
|
72
|
-
|
73
|
-
|
74
|
-
end
|
75
|
-
|
76
|
-
def parsed_type
|
77
|
-
@parsed_type ||=
|
78
|
-
begin
|
79
|
-
(parsed,) = parsed_result
|
80
|
-
parsed
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
136
|
+
##
|
137
|
+
# This type, parsed into an AST.
|
84
138
|
def parsed_result
|
85
139
|
@parsed_result ||= Parser.new(type_for_parser).run_parser
|
86
140
|
end
|
87
141
|
|
142
|
+
##
|
143
|
+
# Standard ruby equality.
|
88
144
|
def eql?(other)
|
89
145
|
other.class == self.class && other.type == type
|
90
146
|
end
|
91
147
|
|
148
|
+
##
|
149
|
+
# Standard ruby hashing method.
|
150
|
+
# Compilers hash to the same value if they are compiling the same type.
|
92
151
|
def hash
|
93
152
|
[self.class, type].hash
|
94
153
|
end
|
95
154
|
|
96
155
|
private
|
97
156
|
|
157
|
+
##
|
158
|
+
# Get metadata attributes to be used if compiling an object schema.
|
159
|
+
#
|
160
|
+
# @return [Hash]
|
161
|
+
def object_schema_meta
|
162
|
+
return {} unless standalone? && type <= SoberSwag::Type::Named
|
163
|
+
|
164
|
+
{
|
165
|
+
description: type.description
|
166
|
+
}.reject { |_, v| v.nil? }
|
167
|
+
end
|
168
|
+
|
169
|
+
def parsed_type
|
170
|
+
@parsed_type ||=
|
171
|
+
begin
|
172
|
+
(parsed,) = parsed_result
|
173
|
+
parsed
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def mapped_type
|
178
|
+
@mapped_type ||= parsed_type.map { |v| SoberSwag::Compiler::Primitive.new(v).type_hash }
|
179
|
+
end
|
180
|
+
|
98
181
|
def generate_schema_stub
|
99
182
|
if type.is_a?(Class)
|
100
183
|
SoberSwag::Compiler::Primitive.new(type).type_hash
|
@@ -2,7 +2,8 @@ require 'active_support/concern'
|
|
2
2
|
|
3
3
|
module SoberSwag
|
4
4
|
##
|
5
|
-
#
|
5
|
+
# This module can be included in any subclass of `ActionController` or `ActionController::API` to make it `SoberSwag`-able.
|
6
|
+
# This means that you can use the mechanics of SoberSwag to define a type-safe API, with generated Swagger documentation!
|
6
7
|
module Controller
|
7
8
|
extend ActiveSupport::Concern
|
8
9
|
|
@@ -17,14 +18,18 @@ module SoberSwag
|
|
17
18
|
include ::Dry::Types()
|
18
19
|
end
|
19
20
|
|
20
|
-
|
21
|
+
##
|
22
|
+
# Module containing class methods.
|
23
|
+
# Any class that `include`s {SoberSwag::Controller} will also `extend` {SoberSwag::Controller::ClassMethods}.
|
24
|
+
module ClassMethods
|
21
25
|
##
|
22
26
|
# Define a new action with the given HTTP method, action name, and path.
|
23
|
-
# This will
|
27
|
+
# This will eventually delegate to making an actual method on your controller,
|
24
28
|
# so you can use controllers as you wish with no harm.
|
25
29
|
#
|
26
30
|
# This method takes a block, evaluated in the context of a {SoberSwag::Controller::Route}.
|
27
31
|
# Used like:
|
32
|
+
#
|
28
33
|
# define(:get, :show, '/posts/{id}') do
|
29
34
|
# path_params do
|
30
35
|
# attribute :id, Types::Integer
|
@@ -36,32 +41,46 @@ module SoberSwag
|
|
36
41
|
# end
|
37
42
|
#
|
38
43
|
# This will define an "action module" on this class to contain the generated types.
|
39
|
-
# In the above example, the following constants will be
|
40
|
-
#
|
41
|
-
#
|
44
|
+
# In the above example, the following constants will be defined on the controller:
|
45
|
+
#
|
46
|
+
# - `PostsController::Show` - the container module for everything in this action
|
47
|
+
# - `PostsController::Show::PathParams` - the dry-struct type for the path attribute.
|
48
|
+
#
|
42
49
|
# So, in the same controller, you can refer to Show::PathParams to get the type created by the 'path_params' block above.
|
50
|
+
#
|
51
|
+
# The block given evaluates in the context of `SoberSwag::Controller::Route`.
|
52
|
+
#
|
53
|
+
# @todo Explore parsing the `path` parameter from rails routes so we can avoid forcing the duplicate boilerplate.
|
54
|
+
#
|
55
|
+
# @param method [Symbol] the HTTP method of this route
|
56
|
+
# @param action [Symbol] the name of the controller method this maps onto
|
57
|
+
# @param path [String] an OpenAPI v3 Path Specifier
|
43
58
|
def define(method, action, path, &block)
|
44
59
|
r = Route.new(method, action, path)
|
45
60
|
r.instance_eval(&block)
|
46
61
|
const_set(r.action_module_name, r.action_module)
|
47
62
|
defined_routes << r
|
48
|
-
define_method(action, r.action) if r.action
|
49
63
|
end
|
50
64
|
|
51
65
|
##
|
52
66
|
# All the routes that this controller knows about.
|
67
|
+
# @return [Array<SoberSwag::Controller::Route>
|
53
68
|
def defined_routes
|
54
69
|
@defined_routes ||= []
|
55
70
|
end
|
56
71
|
|
57
72
|
##
|
58
73
|
# Find a route with the given name.
|
74
|
+
# @param name [Symbol] the name
|
75
|
+
# @return [SoberSwag::Controller::Route]
|
59
76
|
def find_route(name)
|
60
77
|
defined_routes.find { |r| r.action_name.to_s == name.to_s }
|
61
78
|
end
|
62
79
|
|
63
80
|
##
|
64
|
-
#
|
81
|
+
# Get the OpenAPI v3 definition for this controller.
|
82
|
+
#
|
83
|
+
# @return [Hash]
|
65
84
|
def swagger_info
|
66
85
|
@swagger_info ||=
|
67
86
|
begin
|
@@ -74,14 +93,19 @@ module SoberSwag
|
|
74
93
|
end
|
75
94
|
end
|
76
95
|
|
96
|
+
included do |base|
|
97
|
+
base.extend ClassMethods
|
98
|
+
end
|
99
|
+
|
77
100
|
##
|
78
|
-
#
|
101
|
+
# ActiveController action to get the swagger definition for this API.
|
102
|
+
# It renders a JSON of the OpenAPI v3 schema for this API.
|
79
103
|
def swagger
|
80
104
|
render json: self.class.swagger_info
|
81
105
|
end
|
82
106
|
|
83
107
|
##
|
84
|
-
# Get the path parameters, parsed into the type you defined with {SoberSwag::Controller
|
108
|
+
# Get the path parameters, parsed into the type you defined with {SoberSwag::Controller::ClassMethods#define}
|
85
109
|
# @raise [UndefinedPathError] if there's no path params defined for this route
|
86
110
|
# @raise [Dry::Struct::Error] if we cannot convert the path params to the defined type.
|
87
111
|
def parsed_path
|
@@ -95,7 +119,7 @@ module SoberSwag
|
|
95
119
|
end
|
96
120
|
|
97
121
|
##
|
98
|
-
# Get the request body, parsed into the type you defined with {SoberSwag::Controller
|
122
|
+
# Get the request body, parsed into the type you defined with {SoberSwag::Controller::ClassMethods#define}.
|
99
123
|
# @raise [UndefinedBodyError] if there's no request body defined for this route
|
100
124
|
# @raise [Dry::Struct::Error] if we cannot convert the path params to the defined type.
|
101
125
|
def parsed_body
|
@@ -109,7 +133,7 @@ module SoberSwag
|
|
109
133
|
end
|
110
134
|
|
111
135
|
##
|
112
|
-
# Get the query params, parsed into the type you defined with {SoberSwag::Controller
|
136
|
+
# Get the query params, parsed into the type you defined with {SoberSwag::Controller::ClassMethods#define}
|
113
137
|
# @raise [UndefinedQueryError] if there's no query params defined for this route
|
114
138
|
# @raise [Dry::Struct::Error] if we cannot convert the path params to the defined type.
|
115
139
|
def parsed_query
|
@@ -140,6 +164,8 @@ module SoberSwag
|
|
140
164
|
# This kinda violates the "be liberal in what you accept" principle,
|
141
165
|
# but it keeps the docs honest: parameters sent in the body *must* be
|
142
166
|
# in the body.
|
167
|
+
#
|
168
|
+
# @return [Hash]
|
143
169
|
def body_params
|
144
170
|
request.request_parameters
|
145
171
|
end
|
@@ -147,6 +173,7 @@ module SoberSwag
|
|
147
173
|
##
|
148
174
|
# Get the action-definition for the current action.
|
149
175
|
# Under the hood, delegates to the `:action` key of rails params.
|
176
|
+
# @return [SoberSwag::Controller::Route]
|
150
177
|
def current_action_def
|
151
178
|
self.class.find_route(params[:action])
|
152
179
|
end
|
@@ -3,6 +3,12 @@ module SoberSwag
|
|
3
3
|
##
|
4
4
|
# Describe a single controller endpoint.
|
5
5
|
class Route
|
6
|
+
##
|
7
|
+
# @param method [Symbol] the HTTP method to get
|
8
|
+
# @param action_name [Symbol] the name of the rails action
|
9
|
+
# (the name of the controller method, usually)
|
10
|
+
# @param path [String] an OpenAPI V3 path template,
|
11
|
+
# which should [match this format](https://swagger.io/docs/specification/describing-parameters/#path-parameters)
|
6
12
|
def initialize(method, action_name, path)
|
7
13
|
@method = method
|
8
14
|
@path = path
|
@@ -12,20 +18,56 @@ module SoberSwag
|
|
12
18
|
@tags = []
|
13
19
|
end
|
14
20
|
|
15
|
-
|
21
|
+
##
|
22
|
+
# A hash of response code -> response serializer
|
23
|
+
# @return [Hash{Symbol => SoberSwag::Serializer::Base}]
|
24
|
+
# response code to response serializer
|
25
|
+
attr_reader :response_serializers
|
26
|
+
|
27
|
+
##
|
28
|
+
# A hash of response code -> response description
|
29
|
+
# @return [Hash{Symbol => String}]
|
30
|
+
# response code to response description
|
31
|
+
attr_reader :response_descriptions
|
32
|
+
|
33
|
+
##
|
34
|
+
# The HTTP method of this route.
|
35
|
+
# @return [Symbol]
|
36
|
+
attr_reader :method
|
37
|
+
|
38
|
+
##
|
39
|
+
# The swagger path specifier of this route.
|
40
|
+
# @return [String]
|
41
|
+
attr_reader :path
|
42
|
+
|
43
|
+
##
|
44
|
+
# The name of the rails action (usually the controller method) of this route.
|
45
|
+
# @return [Symbol]
|
46
|
+
attr_reader :action_name
|
16
47
|
|
17
48
|
##
|
18
49
|
# What to parse the request body into.
|
50
|
+
# @return [Class] a swagger-able class type for a request body.
|
19
51
|
attr_reader :request_body_class
|
20
52
|
##
|
21
53
|
# What to parse the request query_params into.
|
54
|
+
# @return [Class] a swagger-able class type for query parameters.
|
22
55
|
attr_reader :query_params_class
|
23
56
|
##
|
24
57
|
# What to parse the path params into.
|
58
|
+
# @return [Class] a swagger-able class type for path parameters.
|
25
59
|
attr_reader :path_params_class
|
26
60
|
|
27
61
|
##
|
28
62
|
# Standard swagger tags.
|
63
|
+
#
|
64
|
+
# @overload tags()
|
65
|
+
# Get the tags for this route.
|
66
|
+
# @return [Array<String,Symbol>] the tags.
|
67
|
+
# @overload tags(*args)
|
68
|
+
# Set the tags for this route.
|
69
|
+
# @param tags [Array<String,Symbol>] the tags to set
|
70
|
+
# @return [Array<String,Symbol>] the tags used
|
29
71
|
def tags(*args)
|
30
72
|
return @tags if args.empty?
|
31
73
|
|
@@ -34,8 +76,13 @@ module SoberSwag
|
|
34
76
|
|
35
77
|
##
|
36
78
|
# Define the request body, using SoberSwag's type-definition scheme.
|
37
|
-
# The block passed will be used to define the body of a new
|
38
|
-
#
|
79
|
+
# The block passed will be used to define the body of a new subclass of `base` (defaulted to {SoberSwag::InputObject}.)
|
80
|
+
# @overload request_body(base)
|
81
|
+
# Give a Swagger-able type that will be used to parse the request body, and used in generated docs.
|
82
|
+
# @param base [Class] a swagger-able class
|
83
|
+
# @overload request_body(base = SoberSwag::InputObject, &block)
|
84
|
+
# Define a Swagger-able type inline to use to parse the request body.
|
85
|
+
# @see SoberSwag.input_object
|
39
86
|
def request_body(base = SoberSwag::InputObject, &block)
|
40
87
|
@request_body_class = make_input_object!(base, &block)
|
41
88
|
action_module.const_set('RequestBody', @request_body_class)
|
@@ -48,9 +95,12 @@ module SoberSwag
|
|
48
95
|
end
|
49
96
|
|
50
97
|
##
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
98
|
+
# @overload query_params(base)
|
99
|
+
# Give a Swagger-able type that will be used to parse the query params, and used in generated docs.
|
100
|
+
# @param base [Class] a swagger-able class
|
101
|
+
# @overload query_params(base = SoberSwag::InputObject, &block)
|
102
|
+
# Define a Swagger-able type inline to use to parse the query params.
|
103
|
+
# @see SoberSwag.input_object
|
54
104
|
def query_params(base = SoberSwag::InputObject, &block)
|
55
105
|
@query_params_class = make_input_object!(base, &block)
|
56
106
|
action_module.const_set('QueryParams', @query_params_class)
|
@@ -63,9 +113,12 @@ module SoberSwag
|
|
63
113
|
end
|
64
114
|
|
65
115
|
##
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
116
|
+
# @overload path_params(base)
|
117
|
+
# Give a Swagger-able type that will be used to parse the path params, and used in generated docs.
|
118
|
+
# @param base [Class] a swagger-able class
|
119
|
+
# @overload path_params(base = SoberSwag::InputObject, &block)
|
120
|
+
# Define a Swagger-able type inline to use to parse the path params.
|
121
|
+
# @see SoberSwag.input_object
|
69
122
|
def path_params(base = SoberSwag::InputObject, &block)
|
70
123
|
@path_params_class = make_input_object!(base, &block)
|
71
124
|
action_module.const_set('PathParams', @path_params_class)
|
@@ -78,19 +131,27 @@ module SoberSwag
|
|
78
131
|
end
|
79
132
|
|
80
133
|
##
|
81
|
-
#
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
134
|
+
# @overload description()
|
135
|
+
# Get a description of this route object.
|
136
|
+
# @return [String] markdown-formatted description
|
137
|
+
# @overload description(desc)
|
138
|
+
# Set the description of this route object.
|
139
|
+
# @param desc [String] markdown-formatted description
|
140
|
+
# @return [String] `desc`.
|
88
141
|
def description(desc = nil)
|
89
142
|
return @description if desc.nil?
|
90
143
|
|
91
144
|
@description = desc
|
92
145
|
end
|
93
146
|
|
147
|
+
##
|
148
|
+
# @overload summary()
|
149
|
+
# Get the summary of this route object, a short string that identifies
|
150
|
+
# what it does.
|
151
|
+
# @return [String] markdown-formatted summary
|
152
|
+
# @overload summary(sum)
|
153
|
+
# Set a short, markdown-formatted summary of what this route does.
|
154
|
+
# @param sum [String] markdown-formatted summary
|
94
155
|
def summary(sum = nil)
|
95
156
|
return @summary if sum.nil?
|
96
157
|
|
@@ -100,14 +161,35 @@ module SoberSwag
|
|
100
161
|
##
|
101
162
|
# The container module for all the constants this will eventually define.
|
102
163
|
# Each class generated by this Route will be defined within this module.
|
164
|
+
# @return [Module] the module under which constants will be defined.
|
103
165
|
def action_module
|
104
166
|
@action_module ||= Module.new
|
105
167
|
end
|
106
168
|
|
107
169
|
##
|
108
|
-
#
|
109
|
-
#
|
110
|
-
# {SoberSwag::OutputObject.define}
|
170
|
+
# @overload response(status_code, description, &block)
|
171
|
+
# Define a new response from this route, by defining a serializer inline.
|
172
|
+
# This serializer will be defined as if with {SoberSwag::OutputObject.define}
|
173
|
+
#
|
174
|
+
# Generally, you want to define your serializers elsewhere for independent testing and such.
|
175
|
+
# However, if you have a really quick thing to serialize, this works.
|
176
|
+
# @param status_code [Symbol]
|
177
|
+
# the name of the HTTP status of this response.
|
178
|
+
# @param description [String]
|
179
|
+
# a description of what this response is, markdown-formatted
|
180
|
+
# @param block [Proc]
|
181
|
+
# passed to {SoberSwag::OutputObject.define}
|
182
|
+
#
|
183
|
+
# @overload response(status_code, description, serializer)
|
184
|
+
# Define a new response from this route, with an existing serializer.
|
185
|
+
# The generated swagger will document this response's format using the serializer.
|
186
|
+
#
|
187
|
+
# @param status_code [Symbol]
|
188
|
+
# the name of the HTTP status of this response
|
189
|
+
# @param description [String]
|
190
|
+
# a description of what this response is, markdown-formatted
|
191
|
+
# @param serializer [SoberSwag::Serializer::Base] a serializer to use for the
|
192
|
+
# body of this response
|
111
193
|
def response(status_code, description, serializer = nil, &block)
|
112
194
|
status_key = Rack::Utils.status_code(status_code)
|
113
195
|
|
@@ -120,7 +202,8 @@ module SoberSwag
|
|
120
202
|
end
|
121
203
|
|
122
204
|
##
|
123
|
-
# What you should call the module of this action in your controller
|
205
|
+
# What you should call the module of this action in your controller.
|
206
|
+
# @return [String]
|
124
207
|
def action_module_name
|
125
208
|
action_name.to_s.classify
|
126
209
|
end
|