zero-rails_openapi 1.7.0 → 2.0.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/README.md +404 -434
- data/README_zh.md +5 -5
- data/{documentation/examples → examples}/auto_gen_doc.rb +0 -0
- data/{documentation/examples → examples}/open_api.rb +11 -15
- data/{documentation/examples → examples}/output_example.json +0 -0
- data/lib/oas_objs/callback_obj.rb +5 -10
- data/lib/oas_objs/combined_schema.rb +16 -12
- data/lib/oas_objs/example_obj.rb +9 -7
- data/lib/oas_objs/helpers.rb +4 -20
- data/lib/oas_objs/media_type_obj.rb +10 -10
- data/lib/oas_objs/param_obj.rb +8 -11
- data/lib/oas_objs/ref_obj.rb +2 -0
- data/lib/oas_objs/request_body_obj.rb +6 -2
- data/lib/oas_objs/response_obj.rb +5 -2
- data/lib/oas_objs/schema_obj.rb +48 -67
- data/lib/oas_objs/schema_obj_helpers.rb +11 -35
- data/lib/open_api.rb +57 -6
- data/lib/open_api/config.rb +10 -37
- data/lib/open_api/config_dsl.rb +2 -0
- data/lib/open_api/dsl.rb +36 -49
- data/lib/open_api/dsl/api.rb +63 -68
- data/lib/open_api/dsl/components.rb +34 -24
- data/lib/open_api/dsl/helpers.rb +26 -52
- data/lib/open_api/router.rb +50 -0
- data/lib/open_api/support/tip.rb +26 -0
- data/lib/open_api/version.rb +3 -1
- data/zero-rails_openapi.gemspec +6 -6
- metadata +19 -23
- data/documentation/examples/auto_gen_desc.rb +0 -29
- data/documentation/examples/examples_controller.rb +0 -60
- data/documentation/examples/goods_doc.rb +0 -52
- data/documentation/parameter.md +0 -69
- data/lib/open_api/dsl/common_dsl.rb +0 -39
- data/lib/open_api/generator.rb +0 -116
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 275729646bbe765cc93239a7635934be22850304
|
4
|
+
data.tar.gz: 48e99273f58abd736763251c7eeccdde63d1b4a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d4fcda408a1af25b3d047a0720921688e4f590c7af728982bb0e4c2e0cad562dfbe3c372b4f4a82aa405c715ec1698f3b00ef2998d8a7830dc64c1fec8d90e7
|
7
|
+
data.tar.gz: d0a1461de6816d79c0f7c4a95ce295d7fa5f1aff7c7fbbce34563770a9be52e2b26d0c3847721febc7ca679d7a286fb3da3e5f3fc755187e77d32523c553f9ef
|
data/README.md
CHANGED
@@ -23,42 +23,43 @@
|
|
23
23
|
It may be a very useful tool if you want to write API document clearly.
|
24
24
|
I'm looking forward to your issue and PR!**
|
25
25
|
|
26
|
-
[
|
27
|
-
|
28
|
-
If you have any questions, please read the test code first.
|
29
|
-
such as [api DSL](spec/api_spec.rb) and [schema Obj](spec/oas_objs/schema_obj_spec.rb).
|
26
|
+
(Test cases are rich, like: [api DSL](spec/api_spec.rb) and [schema Obj](spec/oas_objs/schema_obj_spec.rb))
|
30
27
|
|
31
28
|
## Table of Contents
|
32
29
|
|
33
30
|
- [About OAS](#about-oas) (OpenAPI Specification)
|
34
31
|
- [Installation](#installation)
|
35
32
|
- [Configure](#configure)
|
36
|
-
- [Usage
|
37
|
-
- [Basic DSL](#basic-dsl)
|
38
|
-
- [route_base](#1-route_base-
|
39
|
-
- [doc_tag](#2-doc_tag-optional)
|
40
|
-
- [components](#3-components-optional)
|
41
|
-
- [
|
42
|
-
- [
|
43
|
-
- [
|
44
|
-
- [this_api_is_invalid!](#1-this_api_is_invalid-its-aliases)
|
45
|
-
- [desc](#2-desc-description-for-the-current-api
|
46
|
-
- [param family methods](#3-param-family-methods-oas---parameter-object)
|
47
|
-
- [request_body family methods](#4-request_body-family-methods-oas---request-body-object)
|
48
|
-
- [response family methods](#5-response-family-methods-oas---response-object)
|
49
|
-
- [callback](#6-callback-oas---callback-object)
|
50
|
-
- [Authentication and Authorization](#7-authentication-and-authorization)
|
51
|
-
- [server](#8-overriding-global-servers-by-server)
|
52
|
-
|
33
|
+
- [DSL Usage](#dsl-usage)
|
34
|
+
- [a.Basic DSL](#basic-dsl)
|
35
|
+
- [a.1. route_base](#1-route_base-required-if-youre-not-writing-dsl-in-controller)
|
36
|
+
- [a.2. doc_tag](#2-doc_tag-optional)
|
37
|
+
- [a.3. components](#3-components-optional)
|
38
|
+
- [a.4. api](#4-api-required)
|
39
|
+
- [a.5. api_dry](#5-api_dry-optional)
|
40
|
+
- [b. DSLs written inside `api` and `api_dry`'s block](#dsls-written-inside-api-and-api_drys-block)
|
41
|
+
- [b.1. this_api_is_invalid!](#1-this_api_is_invalid-and-its-aliases)
|
42
|
+
- [b.2. desc](#2-desc-description-for-the-current-api)
|
43
|
+
- [b.3. param family methods](#3-param-family-methods-oas---parameter-object)
|
44
|
+
- [b.4. request_body family methods](#4-request_body-family-methods-oas---request-body-object)
|
45
|
+
- [b.5. response family methods](#5-response-family-methods-oas---response-object)
|
46
|
+
- [b.6. callback](#6-callback-oas---callback-object)
|
47
|
+
- [b.7. Authentication and Authorization](#7-authentication-and-authorization)
|
48
|
+
- [b.8. server](#8-overriding-global-servers-by-server)
|
49
|
+
- [b.9. dry](#9-dry)
|
50
|
+
- [c. DSLs written inside `components`'s block](#dsls-written-inside-componentss-block)
|
51
|
+
- [d. Schema and Type](#schema-and-type)
|
52
|
+
- [d.1. (Schema) Type](#schema-type)
|
53
|
+
- [d.2. Schema](#schema)
|
54
|
+
- [d.3. Combined Schema](#combined-schema)
|
53
55
|
- [Run! - Generate JSON documentation file](#run---generate-json-documentation-file)
|
54
56
|
- [Use Swagger UI(very beautiful web page) to show your Documentation](#use-swagger-uivery-beautiful-web-page-to-show-your-documentation)
|
55
57
|
- [Tricks](#tricks)
|
56
58
|
- [Write DSL somewhere else](#trick1---write-the-dsl-somewhere-else)
|
57
59
|
- [Global DRYing](#trick2---global-drying)
|
58
|
-
- [Auto generate description](#trick3---auto-generate-description)
|
60
|
+
- [Auto generate description form enum](#trick3---auto-generate-description-form-enum)
|
59
61
|
- [Skip or Use parameters define in `api_dry`](#trick4---skip-or-use-parameters-define-in-api_dry)
|
60
62
|
- [Atuo Generate index/show Actions's Responses Based on DB Schema](#trick5---auto-generate-indexshow-actionss-response-types-based-on-db-schema)
|
61
|
-
- [Combined Schema (one_of / all_of / any_of / not)](#trick6---combined-schema-one_of--all_of--any_of--not)
|
62
63
|
- [Troubleshooting](#troubleshooting)
|
63
64
|
- [About `OpenApi.docs` and `OpenApi.routes_index`](#about-openapidocs-and-openapiroutes_index)
|
64
65
|
|
@@ -86,10 +87,6 @@
|
|
86
87
|
|
87
88
|
$ bundle
|
88
89
|
|
89
|
-
Or install it yourself as:
|
90
|
-
|
91
|
-
$ gem install zero-rails_openapi
|
92
|
-
|
93
90
|
## Configure
|
94
91
|
|
95
92
|
Create an initializer, configure ZRO and define your OpenApi documents.
|
@@ -97,67 +94,50 @@
|
|
97
94
|
This is the simplest example:
|
98
95
|
|
99
96
|
```ruby
|
100
|
-
# config/initializers/open_api.rb
|
97
|
+
# in config/initializers/open_api.rb
|
101
98
|
require 'open_api'
|
102
99
|
|
103
|
-
OpenApi::Config.
|
104
|
-
#
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
# [REQUIRED] OAS Info Object: The section contains API information.
|
114
|
-
info: {
|
115
|
-
# [REQUIRED] The title of the application.
|
116
|
-
title: 'Homepage APIs',
|
117
|
-
# Description of the application.
|
118
|
-
description: 'API documentation of Rails Application. <br/>' \
|
119
|
-
'Optional multiline or single-line Markdown-formatted description ' \
|
120
|
-
'in [CommonMark](http://spec.commonmark.org/) or `HTML`.',
|
121
|
-
# [REQUIRED] The version of the OpenAPI document
|
122
|
-
# (which is distinct from the OAS version or the API implementation version).
|
123
|
-
version: '1.0.0'
|
124
|
-
}
|
125
|
-
}
|
126
|
-
}
|
100
|
+
OpenApi::Config.class_eval do
|
101
|
+
# Part 1: configs of this gem
|
102
|
+
self.file_output_path = 'public/open_api'
|
103
|
+
|
104
|
+
# Part 2: config (DSL) for generating OpenApi info
|
105
|
+
open_api :doc_name, base_doc_classes: [ApiDoc]
|
106
|
+
info version: '1.0.0', title: 'Homepage APIs'#, description: ..
|
107
|
+
# server 'http://localhost:3000', desc: 'Internal staging server for testing'
|
108
|
+
# bearer_auth :Authorization
|
127
109
|
end
|
128
110
|
```
|
111
|
+
|
112
|
+
### Part 1: configs of this gem
|
129
113
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
114
|
+
1. `file_output_path`(required): The location where .json doc file will be output.
|
115
|
+
2. `default_run_dry`: defaults to run dry blocks even if the `dry` method is not called in the (Basic) DSL block. defaults to `false`.
|
116
|
+
3. `doc_location`: give regular expressions for file or folder paths. `Dir[doc_location]` will be `require` before document generates.
|
117
|
+
this option is only for not writing spec in controllers.
|
118
|
+
4. `rails_routes_file`: give a txt's file path (which's content is the copy of `rails routes`'s output). This will speed up document generation.
|
119
|
+
5. `model_base`: The parent class of models in your application. This option is for auto loading schema from database.
|
120
|
+
6. `file_format`
|
136
121
|
|
137
|
-
|
138
|
-
c.file_output_path = 'public/open_api'
|
122
|
+
### Part 2: config (DSL) for generating OpenApi info
|
139
123
|
|
140
|
-
|
141
|
-
open_api :homepage_api, base_doc_classes: [ApiDoc]
|
142
|
-
info version: '1.0.0', title: 'Homepage APIs'
|
143
|
-
end
|
144
|
-
end
|
145
|
-
```
|
124
|
+
See all the DSLs: [config_dsl.rb](lib/open_api/config_dsl.rb)
|
146
125
|
|
147
|
-
|
148
|
-
See all the settings options: [config.rb](lib/open_api/config.rb)
|
149
|
-
See all the Document Definition DSL: [config_dsl.rb](lib/open_api/config_dsl.rb)
|
126
|
+
## DSL Usage
|
150
127
|
|
151
|
-
|
128
|
+
There are two kinds of DSL for this gem: **basic** and **inside basic**.
|
129
|
+
1. Basic DSLs are class methods which is for declaring your APIs, components, and spec code DRYing ...
|
130
|
+
2. DSLs written inside the block of Basic DSLs, is for declaring the parameters, responses (and so on) of the specified API and component.
|
152
131
|
|
153
|
-
### First of all, `include OpenApi::DSL`
|
132
|
+
### First of all, `include OpenApi::DSL` in your base class (which is for writing spec):
|
154
133
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
134
|
+
For example:
|
135
|
+
```ruby
|
136
|
+
# in app/controllers/api/api_controller.rb
|
137
|
+
class ApiController < ActionController::API
|
138
|
+
include OpenApi::DSL
|
139
|
+
end
|
140
|
+
```
|
161
141
|
|
162
142
|
### DSL Usage Example
|
163
143
|
|
@@ -166,113 +146,115 @@
|
|
166
146
|
```ruby
|
167
147
|
class Api::ExamplesController < ApiController
|
168
148
|
api :index, 'GET list' do
|
169
|
-
query :page, Integer#,
|
149
|
+
query :page, Integer#, range: { ge: 1 }, default: 1
|
170
150
|
query :rows, Integer#, desc: 'per page', range: { ge: 1 }, default: 10
|
171
151
|
end
|
172
152
|
end
|
173
153
|
```
|
174
154
|
|
175
|
-
|
176
|
-
[examples_controller.rb](documentation/examples/examples_controller.rb),
|
177
|
-
or [HERE](https://github.com/zhandao/zero-rails/tree/master/app/_docs/v1).
|
155
|
+
### Basic DSL
|
178
156
|
|
179
|
-
|
157
|
+
[source code](lib/open_api/dsl.rb)
|
180
158
|
|
181
|
-
#### (1) `route_base` [
|
159
|
+
#### (1) `route_base` [required if you're not writing DSL in controller]
|
182
160
|
|
183
161
|
```ruby
|
184
|
-
#
|
185
|
-
route_base
|
186
|
-
#
|
162
|
+
# ** Method Signature
|
163
|
+
route_base path
|
164
|
+
# ** Usage
|
187
165
|
route_base 'api/v1/examples'
|
188
166
|
```
|
189
|
-
It is optional because `route_base` defaults to `controller_path`.
|
190
167
|
|
191
|
-
[
|
192
|
-
to simplify the current controller.
|
168
|
+
[Usage](#trick1---write-the-dsl-somewhere-else): write the DSL somewhere else to simplify the current controller.
|
193
169
|
|
194
170
|
#### (2) `doc_tag` [optional]
|
195
171
|
|
196
172
|
```ruby
|
197
|
-
#
|
198
|
-
doc_tag
|
199
|
-
#
|
200
|
-
doc_tag name: 'ExampleTagName',
|
173
|
+
# ** Method Signature
|
174
|
+
doc_tag name: nil, **tag_info
|
175
|
+
# ** Usage
|
176
|
+
doc_tag name: 'ExampleTagName', description: "ExamplesController's APIs"#, externalDocs: ...
|
201
177
|
```
|
202
|
-
This method allows you to set the Tag (which is a node of [OpenApi Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#openapi-object))
|
178
|
+
This method allows you to set the Tag (which is a node of [OpenApi Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#openapi-object))
|
179
|
+
of all the APIs in the class.
|
203
180
|
|
204
|
-
Tag's name defaults to controller_name.
|
181
|
+
Tag's name defaults to controller_name.
|
205
182
|
|
206
183
|
#### (3) `components` [optional]
|
207
184
|
|
208
185
|
```ruby
|
209
|
-
#
|
186
|
+
# ** Method Signature
|
210
187
|
components(&block)
|
211
|
-
#
|
188
|
+
# ** Usage
|
212
189
|
components do
|
213
|
-
# DSL for defining components
|
190
|
+
# (block inside) DSL for defining components
|
214
191
|
schema :DogSchema => [ { id: Integer, name: String }, dft: { id: 1, name: 'pet' } ]
|
215
192
|
query! :UidQuery => [ :uid, String, desc: 'uid' ]
|
216
|
-
|
193
|
+
response :BadRqResp => [ 'bad request', :json ]
|
217
194
|
end
|
218
195
|
|
219
196
|
# to use component
|
220
|
-
api :action
|
197
|
+
api :action do
|
221
198
|
query :doge, :DogSchema # to use a Schema component
|
222
199
|
param_ref :UidQuery # to use a Parameter component
|
223
200
|
response_ref :BadRqResp # to use a Response component
|
224
201
|
end
|
225
202
|
```
|
226
|
-
Component can be used to simplify your DSL code
|
227
|
-
(that is, to refer to the defined Component object by `*_ref` methods).
|
228
|
-
|
229
203
|
Each RefObj is associated with components through component key.
|
230
|
-
We suggest that component keys should be camelized, and must be Symbol.
|
231
204
|
|
232
|
-
|
205
|
+
We suggest that component keys should be camelized, and **must be Symbol**.
|
206
|
+
|
207
|
+
#### (4) `api` [required]
|
208
|
+
|
209
|
+
For defining API (or we could say controller action).
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
# ** Method Signature
|
213
|
+
api action_name, summary = '', id: nil, tag: nil, http: nil, dry: Config.default_run_dry, &block
|
214
|
+
# ** Usage
|
215
|
+
api :index, '(SUMMARY) this api blah blah ...', # block ...
|
216
|
+
```
|
217
|
+
|
218
|
+
Parameters explanation:
|
219
|
+
1. action_name: must be the same as controller action name
|
220
|
+
2. id: operationId
|
221
|
+
3. http: HTTP method (like: 'GET' or 'GET|POST')
|
222
|
+
|
223
|
+
#### (5) `api_dry` [optional]
|
233
224
|
|
234
225
|
This method is for DRYing.
|
226
|
+
The blocks passed to `api_dry` will be executed to the specified APIs which are having the actions or tags in the class.
|
235
227
|
|
236
228
|
```ruby
|
237
|
-
#
|
238
|
-
api_dry
|
239
|
-
#
|
229
|
+
# ** Method Signature
|
230
|
+
api_dry action_or_tags = :all, &block
|
231
|
+
# ** Usage
|
240
232
|
api_dry :all, 'common response' # block ...
|
241
233
|
api_dry :index # block ...
|
234
|
+
api_dry :TagA # block ...
|
235
|
+
|
242
236
|
api_dry [:index, :show] do
|
243
|
-
query
|
237
|
+
query #...
|
244
238
|
end
|
245
239
|
```
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
#### (5) `api` [required]
|
250
|
-
|
251
|
-
Define the specified API (or we could say controller action).
|
252
|
-
|
253
|
-
```ruby
|
254
|
-
# method signature
|
255
|
-
api(action, summary = '', http: nil, skip: [ ], use: [ ], &block)
|
256
|
-
# usage
|
257
|
-
api :index, '(SUMMARY) this api blah blah ...', # block ...
|
258
|
-
```
|
259
|
-
|
260
|
-
`use` and `skip` options: to use or skip the parameters defined in `api_dry`.
|
261
|
-
|
240
|
+
|
241
|
+
And then you should call `dry` method ([detailed info]()) for executing the declared dry blocks:
|
262
242
|
```ruby
|
263
|
-
api :
|
243
|
+
api :index do
|
244
|
+
dry
|
245
|
+
end
|
264
246
|
```
|
265
247
|
|
266
|
-
###
|
248
|
+
### DSLs written inside [api](#4-api-required) and [api_dry](#5-api_dry-optional)'s block
|
267
249
|
|
268
|
-
[source code](lib/open_api/dsl/
|
250
|
+
[source code](lib/open_api/dsl/api.rb)
|
269
251
|
|
270
252
|
These following methods in the block describe the specified API action: description, valid?,
|
271
|
-
parameters, request body, responses, securities
|
253
|
+
parameters, request body, responses, securities and servers.
|
272
254
|
|
273
255
|
(Here corresponds to OAS [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#operationObject))
|
274
256
|
|
275
|
-
#### (1) `this_api_is_invalid!`, its aliases:
|
257
|
+
#### (1) `this_api_is_invalid!`, and its aliases:
|
276
258
|
```
|
277
259
|
this_api_is_expired!
|
278
260
|
this_api_is_unused!
|
@@ -280,243 +262,207 @@
|
|
280
262
|
```
|
281
263
|
|
282
264
|
```ruby
|
283
|
-
#
|
284
|
-
this_api_is_invalid!(
|
285
|
-
#
|
286
|
-
this_api_is_invalid! '
|
265
|
+
# ** Method Signature
|
266
|
+
this_api_is_invalid!(*)
|
267
|
+
# ** Usage
|
268
|
+
this_api_is_invalid! 'cause old version'
|
287
269
|
```
|
288
270
|
|
289
|
-
|
271
|
+
After that, `deprecated` field of this API will be set to true.
|
290
272
|
|
291
|
-
#### (2) `desc`: description for the current API
|
273
|
+
#### (2) `desc`: description for the current API
|
292
274
|
|
293
275
|
```ruby
|
294
|
-
#
|
295
|
-
desc
|
296
|
-
#
|
297
|
-
desc "current API's description"
|
298
|
-
id: 'desc of the parameter :id',
|
299
|
-
email: 'desc of the parameter :email'
|
276
|
+
# ** Method Signature
|
277
|
+
desc string
|
278
|
+
# ** Usage
|
279
|
+
desc "current API's description"
|
300
280
|
```
|
301
281
|
|
302
|
-
You can of course describe the input in it's DSL method (like `query! :done ...`, [this line](https://github.com/zhandao/zero-rails_openapi#dsl-usage-example)),
|
303
|
-
but that will make it long and ugly. We recommend that unite descriptions in this place.
|
304
|
-
|
305
|
-
In addition, when you want to dry the same parameters (each with a different description), it will be of great use.
|
306
|
-
|
307
282
|
#### (3) `param` family methods (OAS - [Parameter Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#parameterObject))
|
308
283
|
|
309
|
-
|
284
|
+
To define parameter for APIs.
|
310
285
|
```
|
311
|
-
param
|
312
|
-
param_ref #
|
313
|
-
|
314
|
-
header
|
315
|
-
|
316
|
-
|
317
|
-
order # order parameters by names array you passed
|
318
|
-
examples # define examples of parameters
|
286
|
+
param # 1. normal usage
|
287
|
+
param_ref # 2. links sepcified RefObjs (by component keys) to current parameters.
|
288
|
+
header, path, query, cookie # 3. passes specified parameter location (like header) to `param`
|
289
|
+
header!, path!, query!, cookie! # 4. bang method of above methods
|
290
|
+
in_* by: { parameter_definations } # 5. batch definition, such as `in_path`, `in_query`
|
291
|
+
examples # 6. examples of parameters
|
319
292
|
```
|
320
|
-
**The bang method (which's name is end of a exclamation point `!`) means this param is required
|
321
|
-
**THE SAME BELOW.**
|
293
|
+
**The bang method and param_name (which's name is end of a exclamation point `!`) means this param is required. Without `!` means optional. THE SAME BELOW.**
|
322
294
|
|
323
295
|
```ruby
|
324
|
-
#
|
325
|
-
#
|
326
|
-
#
|
327
|
-
#
|
328
|
-
|
329
|
-
#
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
#
|
336
|
-
|
337
|
-
param_ref
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
header
|
347
|
-
query!
|
348
|
-
# The same effect as above, but not
|
349
|
-
param :query, :readed, Boolean, :req,
|
350
|
-
|
351
|
-
#
|
352
|
-
#
|
353
|
-
|
354
|
-
#
|
355
|
-
|
356
|
-
#
|
357
|
-
query :good_name, type: String # It's also OK, but some superfluous
|
358
|
-
query :good_name, String # recommended
|
359
|
-
# About Combined Schema (`one_of` ..), see the link below.
|
360
|
-
|
361
|
-
|
362
|
-
# method signature
|
363
|
-
do_query(by:)
|
364
|
-
# usage
|
365
|
-
do_query by: {
|
296
|
+
# Part 1
|
297
|
+
# param_type: location of parameter, like: query, path [A]
|
298
|
+
# param_name: name of parameter, it can be Symbol or String [B]
|
299
|
+
# schema_type: type of parameter, like: String, Integer (must be a constant). see #schema-and-type
|
300
|
+
# required: :required / :req OR :optional / :opt
|
301
|
+
# schema: see #schema-and-type (including combined schema)
|
302
|
+
# ** Method Signature
|
303
|
+
param param_type, param_name, schema_type, required, schema = { }
|
304
|
+
# ** Usage
|
305
|
+
param :query, :page, Integer, :req, range: { gt: 0, le: 5 }, desc: 'page number'
|
306
|
+
|
307
|
+
# Part 2
|
308
|
+
# ** Method Signature
|
309
|
+
param_ref *component_key # should pass at least 1 key
|
310
|
+
# ** Usage
|
311
|
+
param_ref :IdPath#, :NameQuery, :TokenHeader
|
312
|
+
|
313
|
+
# Part 3 & 4
|
314
|
+
# ** Method Signature
|
315
|
+
header param_name, schema_type = nil, **schema
|
316
|
+
query! param_name, schema_type = nil, **schema
|
317
|
+
# ** Usage
|
318
|
+
header :'X-Token', String
|
319
|
+
query! :readed, Boolean, default: false
|
320
|
+
# The same effect as above, but not concise
|
321
|
+
param :query, :readed, Boolean, :req, default: false
|
322
|
+
|
323
|
+
# Part 5
|
324
|
+
# ** Method Signature
|
325
|
+
in_query **params_and_schema
|
326
|
+
# ** Usage
|
327
|
+
in_query(
|
366
328
|
search_type: String,
|
367
329
|
search_val: String,
|
368
|
-
export!: Boolean
|
369
|
-
|
370
|
-
# The same effect as above
|
330
|
+
export!: { type: Boolean, desc: 'export as pdf' }
|
331
|
+
)
|
332
|
+
# The same effect as above
|
371
333
|
query :search_type, String
|
372
334
|
query :search_val, String
|
373
|
-
query! :export, Boolean
|
374
|
-
|
375
|
-
|
376
|
-
#
|
377
|
-
|
378
|
-
|
379
|
-
#
|
380
|
-
#
|
381
|
-
|
335
|
+
query! :export, Boolean, desc: 'export as pdf'
|
336
|
+
|
337
|
+
# Part 6
|
338
|
+
# ** Method Signature
|
339
|
+
examples exp_params = :all, examples_hash
|
340
|
+
# ** Usage
|
341
|
+
# Suppose we have three parameters: id, name, age
|
342
|
+
# * normal
|
343
|
+
examples(
|
344
|
+
right_input: [ 1, 'user', 26 ],
|
345
|
+
wrong_input: [ 2, 'resu', 35 ]
|
346
|
+
)
|
347
|
+
# * using exp_params
|
382
348
|
examples [:id, :name], {
|
383
|
-
|
384
|
-
|
349
|
+
right_input: [ 1, 'user' ],
|
350
|
+
wrong_input: [ 2, 'resu' ]
|
385
351
|
}
|
386
352
|
```
|
387
353
|
|
388
|
-
[
|
354
|
+
[A] OpenAPI 3.0 distinguishes between the following parameter types based on the parameter location:
|
355
|
+
**header, path, query, cookie**. [more info](https://swagger.io/docs/specification/describing-parameters/)
|
389
356
|
|
390
|
-
[
|
357
|
+
[B] If `param_type` is path, for example: if the API path is `/good/:id`, you have to declare a path parameter named `id`
|
391
358
|
|
392
359
|
#### (4) `request_body` family methods (OAS - [Request Body Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#requestBodyObject))
|
393
360
|
|
394
361
|
OpenAPI 3.0 uses the requestBody keyword to distinguish the payload from parameters.
|
362
|
+
|
363
|
+
Notice: Each API has only ONE request body object. Each request body object can has multiple media types.
|
364
|
+
It means: call `request_body` multiple times, (schemas) will be deeply merged (let's call it [fusion](#fusion)) into a request body object.
|
395
365
|
```
|
396
|
-
request_body
|
397
|
-
body_ref #
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
data # define [a] property in the form-data body
|
402
|
-
file, file! # define a File media-type body
|
366
|
+
request_body # 1. normal usage
|
367
|
+
body_ref # 2. it links sepcified RefObjs (by component keys) to the body.
|
368
|
+
body, body! # 3. alias of request_body
|
369
|
+
form, form! # 4. to define a multipart/form-data request_body
|
370
|
+
data # 5. to define [a] property in the form-data request_body
|
403
371
|
```
|
404
372
|
Bang methods(!) means the specified media-type body is required.
|
405
373
|
|
406
374
|
```ruby
|
407
|
-
#
|
408
|
-
|
409
|
-
#
|
410
|
-
#
|
411
|
-
#
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
#
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
#
|
422
|
-
|
423
|
-
|
375
|
+
# Part 1
|
376
|
+
# ** Method Signature
|
377
|
+
# a. `data` contains the attributes (params, or properties) and their schemas required by the request body
|
378
|
+
# b. `attr_name!` means it is required, without '!' means optional
|
379
|
+
# c. options: desc / exp_params and examples
|
380
|
+
# d. available `media_type` see:
|
381
|
+
# https://github.com/zhandao/zero-rails_openapi/blob/master/lib/oas_objs/media_type_obj.rb#L29
|
382
|
+
request_body required, media_type, data: { }, desc: '', **options
|
383
|
+
# ** Usage
|
384
|
+
request_body :opt, :form, data: {
|
385
|
+
id!: Integer,
|
386
|
+
name: { type: String, desc: 'name' }
|
387
|
+
}, desc: 'a form-data'
|
388
|
+
|
389
|
+
# Part 2
|
390
|
+
# ** Method Signature
|
391
|
+
body_ref component_key
|
392
|
+
# ** Usage
|
393
|
+
body_ref :UpdateUserBody
|
394
|
+
|
395
|
+
# Part 3
|
396
|
+
# ** Method Signature
|
397
|
+
body! media_type, data: { }, **options
|
398
|
+
# ** Usage
|
424
399
|
body :json
|
425
400
|
|
426
|
-
|
427
|
-
# method
|
428
|
-
def form data:, **options
|
401
|
+
# Part 4
|
402
|
+
# ** method Implement
|
403
|
+
def form data:, **options # or `form!`
|
429
404
|
body :form, data: data, **options
|
430
405
|
end
|
431
|
-
#
|
406
|
+
# ** Usage
|
432
407
|
form! data: {
|
433
|
-
|
434
|
-
password: String,
|
435
|
-
password_confirmation: String
|
408
|
+
name!: String,
|
409
|
+
password: { type: String, pattern: /[0-9]{6,10}/ },
|
436
410
|
}
|
437
|
-
# advance usage
|
438
|
-
form data: {
|
439
|
-
:name! => { type: String, desc: 'user name' },
|
440
|
-
:password! => { type: String, pattern: /[0-9]{6,10}/, desc: 'password' },
|
441
|
-
# optional
|
442
|
-
:remarks => { type: String, desc: 'remarks' },
|
443
|
-
}, exp_by: %i[ name password ],
|
444
|
-
examples: { # ↓ ↓
|
445
|
-
:right_input => [ 'user1', '123456' ],
|
446
|
-
:wrong_input => [ 'user2', 'abc' ]
|
447
|
-
},
|
448
|
-
desc: 'for creating a user'
|
449
|
-
|
450
|
-
|
451
|
-
# method implement
|
452
|
-
def data name, type = nil, schema_info = { }
|
453
|
-
schema_info[:type] = type if type.present?
|
454
|
-
form data: { name => schema_info }
|
455
|
-
end
|
456
|
-
# usage: please look at the 4th point below
|
457
411
|
|
458
|
-
#
|
459
|
-
|
460
|
-
|
461
|
-
|
412
|
+
# Part 5
|
413
|
+
# ** Method Signature
|
414
|
+
data name, type = nil, schema = { }
|
415
|
+
# ** Usage
|
416
|
+
data :password!, String, pattern: /[0-9]{6,10}/
|
417
|
+
```
|
418
|
+
|
419
|
+
<a name="fusion"></a>
|
420
|
+
How **fusion** works:
|
421
|
+
1. Difference media types will be merged into `requestBody["content"]`
|
422
|
+
|
423
|
+
```ruby
|
424
|
+
form data: { }
|
425
|
+
body :json, data: { }
|
426
|
+
# will generate: "content": { "multipart/form-data": { }, "application/json": { } }
|
462
427
|
```
|
463
428
|
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
```
|
480
|
-
(2) The same media-types will fusion, but not merge:
|
481
|
-
(So that you can write `form` separately, and make `data` method possible.)
|
482
|
-
```ruby
|
483
|
-
data :param_a!, String
|
484
|
-
data :param_b, Integer
|
485
|
-
# or same as:
|
486
|
-
form data: { :param_a! => String }
|
487
|
-
form data: { :param_b => Integer }
|
488
|
-
# will generate: { "param_a": { "type": "string" }, "param_b": { "type": "integer" } } (call it X)
|
489
|
-
# therefore:
|
490
|
-
# "content": { "multipart/form-data":
|
491
|
-
# { "schema": { "type": "object", "properties": { X }, "required": [ "param_a" ] }
|
492
|
-
# }
|
493
|
-
```
|
429
|
+
2. The same media-types will be deeply merged together, including their `required` array:
|
430
|
+
(So that you can call `form` multiple times)
|
431
|
+
|
432
|
+
```ruby
|
433
|
+
data :param_a!, String
|
434
|
+
data :param_b, Integer
|
435
|
+
# or same as:
|
436
|
+
form data: { :param_a! => String }
|
437
|
+
form data: { :param_b => Integer }
|
438
|
+
# will generate: { "param_a": { "type": "string" }, "param_b": { "type": "integer" } } (call it X)
|
439
|
+
# therefore:
|
440
|
+
# "content": { "multipart/form-data":
|
441
|
+
# { "schema": { "type": "object", "properties": { X }, "required": [ "param_a" ] }
|
442
|
+
# }
|
443
|
+
```
|
494
444
|
|
495
445
|
#### (5) `response` family methods (OAS - [Response Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#response-object))
|
496
446
|
|
497
|
-
|
447
|
+
To define the response for APIs.
|
498
448
|
```
|
499
|
-
response # aliases: `resp` and `error`
|
500
|
-
response_ref
|
449
|
+
response # 1. aliases: `resp` and `error`
|
450
|
+
response_ref # 2. it links sepcified RefObjs (by component keys) to the response.
|
501
451
|
```
|
502
452
|
|
503
453
|
```ruby
|
504
|
-
#
|
505
|
-
response
|
506
|
-
#
|
507
|
-
resp 200, '
|
508
|
-
response 200, 'query result', :pdf, type: File
|
509
|
-
# same as:
|
454
|
+
# ** Method Signature
|
455
|
+
response code, desc, media_type = nil, data: { }
|
456
|
+
# ** Usage
|
457
|
+
resp 200, 'success', :json, data: { name: 'test' }
|
510
458
|
response 200, 'query result', :pdf, data: File
|
511
459
|
|
512
|
-
#
|
513
|
-
response_ref
|
514
|
-
#
|
460
|
+
# ** Method Signature
|
461
|
+
response_ref code_and_compkey_hash
|
462
|
+
# ** Usage
|
515
463
|
response_ref 700 => :AResp, 800 => :BResp
|
516
464
|
```
|
517
465
|
|
518
|
-
**practice:** Automatically generate responses based on the agreed error class. [AutoGenDoc](documentation/examples/auto_gen_doc.rb#L63)
|
519
|
-
|
520
466
|
### (6) Callback (OAS - [Callback Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#callback-object))
|
521
467
|
|
522
468
|
[About Callbacks](https://swagger.io/docs/specification/callbacks/)
|
@@ -537,11 +483,11 @@
|
|
537
483
|
...
|
538
484
|
```
|
539
485
|
|
540
|
-
|
486
|
+
`callback` method is for defining callbacks.
|
541
487
|
```ruby
|
542
|
-
#
|
543
|
-
callback
|
544
|
-
#
|
488
|
+
# ** Method Signature
|
489
|
+
callback event_name, http_method, callback_url, &block
|
490
|
+
# ** Usage
|
545
491
|
callback :myEvent, :post, 'localhost:3000/api/goods' do
|
546
492
|
query :name, String
|
547
493
|
data :token, String
|
@@ -564,7 +510,7 @@
|
|
564
510
|
|
565
511
|
##### Define Security Scheme
|
566
512
|
|
567
|
-
Use these DSL in your initializer or `components` block
|
513
|
+
Use these DSL **in your initializer config or `components` block**:
|
568
514
|
```
|
569
515
|
security_scheme # alias `auth_scheme`
|
570
516
|
base_auth # will call `security_scheme`
|
@@ -573,17 +519,17 @@
|
|
573
519
|
```
|
574
520
|
It's very simple to use (if you understand the above document)
|
575
521
|
```ruby
|
576
|
-
#
|
577
|
-
security_scheme
|
578
|
-
#
|
522
|
+
# ** Method Signature
|
523
|
+
security_scheme scheme_name, other_info
|
524
|
+
# ** Usage
|
579
525
|
security_scheme :BasicAuth, { type: 'http', scheme: 'basic', desc: 'basic auth' }
|
580
526
|
|
581
|
-
#
|
582
|
-
base_auth
|
583
|
-
bearer_auth
|
584
|
-
api_key
|
585
|
-
#
|
586
|
-
base_auth :BasicAuth, desc: 'basic auth' # the same effect as
|
527
|
+
# ** Method Signature
|
528
|
+
base_auth scheme_name, other_info = { }
|
529
|
+
bearer_auth scheme_name, format = 'JWT', other_info = { }
|
530
|
+
api_key scheme_name, field:, in:, **other_info
|
531
|
+
# ** Usage
|
532
|
+
base_auth :BasicAuth, desc: 'basic auth' # the same effect as above
|
587
533
|
bearer_auth :Token
|
588
534
|
api_key :ApiKeyAuth, field: 'X-API-Key', in: 'header', desc: 'pass api key to header'
|
589
535
|
```
|
@@ -591,98 +537,166 @@
|
|
591
537
|
##### Apply Security
|
592
538
|
|
593
539
|
```
|
594
|
-
#
|
595
|
-
#
|
596
|
-
global_security_require
|
597
|
-
global_security # alias
|
598
|
-
global_auth # alias
|
540
|
+
# Use in initializer (Global effectiveness)
|
541
|
+
global_security_require # alias: global_security & global_auth
|
599
542
|
|
600
|
-
#
|
601
|
-
#
|
602
|
-
security_require
|
603
|
-
security # alias
|
604
|
-
auth # alias
|
605
|
-
need_auth # alias
|
543
|
+
# Use in `api`'s block (Only valid for the current controller)
|
544
|
+
security_require # alias security & auth_with
|
606
545
|
```
|
607
|
-
Name is different, signature and usage is similar.
|
608
546
|
```ruby
|
609
|
-
#
|
610
|
-
security_require
|
611
|
-
#
|
547
|
+
# ** Method Signature
|
548
|
+
security_require scheme_name, scopes: [ ]
|
549
|
+
# ** Usage
|
612
550
|
global_auth :Token
|
613
|
-
|
614
|
-
auth :OAuth, scopes: %w[ read_example admin ]
|
551
|
+
auth_with :OAuth, scopes: %w[ read_example admin ]
|
615
552
|
```
|
616
553
|
|
617
554
|
#### (8) Overriding Global Servers by `server`
|
618
555
|
|
619
556
|
```ruby
|
620
|
-
#
|
621
|
-
server
|
622
|
-
#
|
557
|
+
# ** Method Signature
|
558
|
+
server url, desc: ''
|
559
|
+
# ** Usage
|
623
560
|
server 'http://localhost:3000', desc: 'local'
|
624
561
|
```
|
562
|
+
|
563
|
+
#### (9) `dry`
|
625
564
|
|
626
|
-
|
565
|
+
You have to call `dry` method inside `api` block, or pass `dry: true` as parameter of `api`,
|
566
|
+
for executing the dry blocks you declared before. Otherwise nothing will happen.
|
567
|
+
|
568
|
+
```ruby
|
569
|
+
# ** Method Signature
|
570
|
+
dry only: nil, skip: nil, none: false
|
571
|
+
|
572
|
+
# ** Usage
|
573
|
+
# In general, just:
|
574
|
+
dry
|
575
|
+
# To skip some params declared in dry blocks:
|
576
|
+
dry skip: [:id, :name]
|
577
|
+
# `only` is used to specify which parameters will be taken from dry blocks
|
578
|
+
dry only: [:id]
|
579
|
+
```
|
627
580
|
|
628
|
-
|
581
|
+
### DSLs written inside [components](#3-components-optional)'s block
|
582
|
+
[code source](lib/open_api/dsl/components.rb) (Here corresponds to OAS [Components Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#componentsObject))
|
629
583
|
|
630
584
|
Inside `components`'s block,
|
631
|
-
you can use the same
|
632
|
-
But there are two differences:
|
633
|
-
|
634
|
-
(1) Each method needs to pass one more parameter `component_key`
|
635
|
-
(in the first parameter position),
|
636
|
-
this will be used as the reference name for the component.
|
585
|
+
you can use the same DSLs as [DSLs written inside `api` and `api_dry`'s block](#dsls-written-inside-api-and-api_drys-block).
|
586
|
+
But notice there are two differences:
|
637
587
|
|
638
|
-
|
639
|
-
|
640
|
-
```
|
641
|
-
This writing is feasible but not recommended,
|
642
|
-
because component's key and parameter's name seem easy to confuse.
|
643
|
-
The recommended writing is:
|
588
|
+
(1) Each method needs to pass one more parameter `component_key` (as the first parameter),
|
589
|
+
it will be used as the reference name for the component.
|
644
590
|
|
645
591
|
```ruby
|
646
|
-
query! :UidQuery
|
592
|
+
query! :UidQuery, :uid, String, desc: 'it is a component'
|
593
|
+
# ↑ ↑
|
594
|
+
# component_key param_name
|
595
|
+
|
596
|
+
# You can also use "arrow writing", it may be easier to understand
|
597
|
+
query! :UidQuery => [:uid, String, desc: '']
|
647
598
|
```
|
648
599
|
|
649
600
|
(2) You can use `schema` to define a Schema Component.
|
650
601
|
|
651
602
|
```ruby
|
652
|
-
#
|
653
|
-
schema
|
654
|
-
#
|
655
|
-
schema :Dog => [ String, desc: '
|
603
|
+
# ** Method Signature
|
604
|
+
schema component_key, type = nil, **schema
|
605
|
+
# ** Usage
|
606
|
+
schema :Dog => [ String, desc: 'doge' ]
|
656
607
|
# advance usage
|
657
608
|
schema :Dog => [
|
658
609
|
{
|
659
|
-
|
660
|
-
name: { type: String,
|
661
|
-
},
|
662
|
-
dft: { id: 1, name: 'pet' },
|
663
|
-
desc: 'dogee'
|
610
|
+
id!: Integer,
|
611
|
+
name: { type: String, desc: 'doge name' }
|
612
|
+
}, default: { id: 1, name: 'pet' }
|
664
613
|
]
|
665
|
-
# or
|
666
|
-
schema :Dog, { id!: Integer, name: String },
|
614
|
+
# or flatten writing
|
615
|
+
schema :Dog, { id!: Integer, name: String }, default: { id: 1, name: 'pet' }
|
667
616
|
#
|
668
617
|
# pass a ActiveRecord class constant as `component_key`,
|
669
|
-
# it will automatically
|
618
|
+
# it will automatically load schema from database and then generate the component.
|
670
619
|
schema User # easy! And the component_key will be :User
|
671
620
|
```
|
672
|
-
|
621
|
+
To enable load schema from database, you must set [model base](#part-1-configs-of-this-gem) correctly.
|
622
|
+
|
623
|
+
### Schema and Type
|
624
|
+
|
625
|
+
schema and type -- contain each other
|
626
|
+
|
627
|
+
#### (Schema) Type
|
628
|
+
|
629
|
+
Support all [data types](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#dataTypes) in OAS.
|
630
|
+
|
631
|
+
1. String / 'binary' / 'base64' / 'uri'
|
632
|
+
2. Integer / Long / 'int32' / 'int64' / Float / Double
|
633
|
+
3. File (it will be converted to `{ type: 'string', format: Config.file_format }`)
|
634
|
+
4. Date / DateTime
|
635
|
+
5. 'boolean'
|
636
|
+
6. Array / Array[\<Type\>] (like: `Array[String]`, `[String]`)
|
637
|
+
7. Nested Array (like: `[[[Integer]]]`)
|
638
|
+
8. Object / Hash (Object with properties)
|
639
|
+
Example: `{ id!: Integer, name: String }`
|
640
|
+
9. Nested Hash: `{ id!: Integer, name: { first: String, last: String } }`
|
641
|
+
10. Nested Array[Nested Hash]: `[[{ id!: Integer, name: { first: String, last: String } }]]`
|
642
|
+
11. Symbol Value: it will generate a Schema Reference Object link to the component correspond to ComponentKey, like: :IdPath, :NameQuery
|
643
|
+
|
644
|
+
**Notice** that Symbol is not allowed in all cases except 11.
|
645
|
+
|
646
|
+
#### Schema
|
647
|
+
|
648
|
+
[OAS Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#schemaObject)
|
649
|
+
and [source code](https://github.com/zhandao/zero-rails_openapi/blob/master/lib/oas_objs/schema_obj.rb)
|
650
|
+
|
651
|
+
Schema (Hash) is for defining properties of parameters, responses and request bodies.
|
652
|
+
|
653
|
+
The following property keys will be process slightly:
|
654
|
+
1. desc / description / d
|
655
|
+
2. enum / in / values / allowable_values
|
656
|
+
should be Array or Range
|
657
|
+
3. range: allow value in this continuous range
|
658
|
+
should be Range or like `{ gt: 0, le: 5 }`
|
659
|
+
4. length / size / lth
|
660
|
+
should be an Integer, Integer Array, Integer Range,
|
661
|
+
or the following format Symbol: `:gt_`, `:ge_`, `:lt_`, `:le_` (:ge_5 means "greater than or equal 5"; :lt_9 means "lower than 9")
|
662
|
+
5. pattern / regxp
|
663
|
+
6. additional_properties / add_prop / values_type
|
664
|
+
7. example
|
665
|
+
8. examples
|
666
|
+
9. format
|
667
|
+
10. default: default value
|
668
|
+
11. type
|
669
|
+
|
670
|
+
The other keys will be directly merged. Such as:
|
671
|
+
1. `title: 'Property Title'`
|
672
|
+
2. `myCustomKey: 'Value'`
|
673
|
+
|
674
|
+
#### Combined Schema
|
675
|
+
|
676
|
+
Very easy to use:
|
677
|
+
```ruby
|
678
|
+
query :combination, one_of: [ :GoodSchema, String, { type: Integer, desc: 'integer input' } ]
|
679
|
+
|
680
|
+
form data: {
|
681
|
+
:combination_in_form => { any_of: [ Integer, String ] }
|
682
|
+
}
|
683
|
+
|
684
|
+
schema :PetSchema => [ not: [ Integer, Boolean ] ]
|
685
|
+
```
|
686
|
+
|
687
|
+
OAS: [link1](https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/),
|
688
|
+
[link2](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject)
|
673
689
|
|
674
690
|
## Run! - Generate JSON Documentation File
|
675
691
|
|
676
692
|
Use `OpenApi.write_docs`:
|
677
693
|
|
678
694
|
```ruby
|
679
|
-
#
|
680
|
-
OpenApi.write_docs generate_files: !Rails.env.production?
|
681
|
-
|
682
|
-
# or run directly in console
|
683
|
-
OpenApi.write_docs # will generate json doc files
|
695
|
+
OpenApi.write_docs# if: !Rails.env.production?
|
684
696
|
```
|
685
697
|
|
698
|
+
`if` option is used to control whether a JSON document is generated or not.
|
699
|
+
|
686
700
|
Then the JSON files will be written to the directories you set. (Each API a file.)
|
687
701
|
|
688
702
|
## Use Swagger UI(very beautiful web page) to show your Documentation
|
@@ -735,31 +749,20 @@
|
|
735
749
|
|
736
750
|
Method `api_dry` is for DRY but its scope is limited to the current controller.
|
737
751
|
|
738
|
-
I have no idea of best practices, But you can look at this [file](
|
752
|
+
I have no idea of best practices, But you can look at this [file](examples/auto_gen_doc.rb).
|
739
753
|
The implementation of the file is: do `api_dry` when inherits the base controller inside `inherited` method.
|
740
754
|
|
741
755
|
You can use `sort` to specify the order of parameters.
|
742
756
|
|
743
|
-
### Trick3 - Auto Generate Description
|
757
|
+
### Trick3 - Auto Generate Description from Enum
|
744
758
|
|
759
|
+
Just use `enum!`:
|
745
760
|
```ruby
|
746
|
-
desc '
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
# or
|
751
|
-
|
752
|
-
query :search_type, String, desc!: 'search field, allows:<br/>',
|
753
|
-
enum: %w[name creator category price]
|
761
|
+
query :search_type, String, desc: 'search field, allows:<br/>', enum!: %w[name creator category price]
|
762
|
+
# it will generate:
|
763
|
+
"search field, allows:<br/>1/ name<br/>2/ creator,<br/>3/ category<br/>4/ price<br/>"
|
754
764
|
```
|
755
|
-
|
756
|
-
Notice `!` use (`search_type!`, `desc!`), it tells ZRO to append
|
757
|
-
information that analyzed from definitions (enum, must_be ..) to description automatically.
|
758
|
-
|
759
|
-
Any one of above will generate:
|
760
|
-
> search field, allows:<br/>1/ name<br/>2/ creator,<br/>3/ category<br/>4/ price<br/>
|
761
|
-
|
762
|
-
You can also use Hash to define `enum`:
|
765
|
+
Or Hash `enum!`:
|
763
766
|
```ruby
|
764
767
|
query :view, String, desc: 'allows values<br/>', enum!: {
|
765
768
|
'all goods (default)': :all,
|
@@ -769,37 +772,6 @@
|
|
769
772
|
'cheap goods': :borrow,
|
770
773
|
}
|
771
774
|
```
|
772
|
-
Read this [file](documentation/examples/auto_gen_desc.rb) to learn more.
|
773
|
-
|
774
|
-
### Trick4 - Skip or Use parameters define in api_dry
|
775
|
-
|
776
|
-
Pass `skip: []` and `use: []` to `api` like following code:
|
777
|
-
```ruby
|
778
|
-
api :index, 'desc', skip: [ :Token ]
|
779
|
-
```
|
780
|
-
|
781
|
-
Look at this [file](documentation/examples/goods_doc.rb) to learn more.
|
782
|
-
|
783
|
-
### Trick5 - Auto Generate index/show Actions's Response-Types Based on DB Schema
|
784
|
-
|
785
|
-
Use method `load_schema` in `api_dry`.
|
786
|
-
|
787
|
-
See this [file](documentation/examples/auto_gen_doc.rb#L51) for uasge information.
|
788
|
-
|
789
|
-
### Trick6 - Combined Schema (one_of / all_of / any_of / not)
|
790
|
-
|
791
|
-
```ruby
|
792
|
-
query :combination, one_of: [ :GoodSchema, String, { type: Integer, desc: 'integer input' } ]
|
793
|
-
|
794
|
-
form data: {
|
795
|
-
:combination_in_form => { any_of: [ Integer, String ] }
|
796
|
-
}
|
797
|
-
|
798
|
-
schema :PetSchema => [ not: [ Integer, Boolean ] ]
|
799
|
-
```
|
800
|
-
|
801
|
-
OAS: [link1](https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/),
|
802
|
-
[link2](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject)
|
803
775
|
|
804
776
|
## Troubleshooting
|
805
777
|
|
@@ -826,8 +798,6 @@
|
|
826
798
|
|
827
799
|
## Development
|
828
800
|
|
829
|
-
TODO ..
|
830
|
-
|
831
801
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
832
802
|
|
833
803
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
@@ -838,4 +808,4 @@
|
|
838
808
|
|
839
809
|
## Code of Conduct
|
840
810
|
|
841
|
-
Everyone interacting in the Zero-
|
811
|
+
Everyone interacting in the Zero-RailsOpenApi project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).
|