zero-rails_openapi 1.5.2 → 1.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/Gemfile.lock +5 -3
- data/README.md +149 -149
- data/README_zh.md +183 -167
- data/documentation/examples/examples_controller.rb +1 -1
- data/documentation/parameter.md +3 -3
- data/lib/oas_objs/param_obj.rb +7 -18
- data/lib/oas_objs/ref_obj.rb +2 -1
- data/lib/oas_objs/schema_obj.rb +26 -62
- data/lib/oas_objs/schema_obj_helpers.rb +37 -21
- data/lib/open_api/dsl/api_info.rb +24 -41
- data/lib/open_api/dsl/common_dsl.rb +3 -2
- data/lib/open_api/dsl/components.rb +25 -33
- data/lib/open_api/dsl/helpers.rb +24 -8
- data/lib/open_api/dsl.rb +3 -2
- data/lib/open_api/generator.rb +7 -7
- data/lib/open_api/version.rb +1 -1
- data/zero-rails_openapi.gemspec +3 -0
- metadata +16 -2
data/README.md
CHANGED
@@ -5,8 +5,9 @@
|
|
5
5
|
[![Maintainability](https://api.codeclimate.com/v1/badges/471fd60f6eb7b019ceed/maintainability)](https://codeclimate.com/github/zhandao/zero-rails_openapi/maintainability)
|
6
6
|
[![Test Coverage](https://api.codeclimate.com/v1/badges/471fd60f6eb7b019ceed/test_coverage)](https://codeclimate.com/github/zhandao/zero-rails_openapi/test_coverage)
|
7
7
|
[![Gitter Chat](https://badges.gitter.im/zero-rails_openapi/Lobby.svg)](https://gitter.im/zero-rails_openapi/Lobby)
|
8
|
-
|
9
|
-
|
8
|
+
[![Help Contribute to Open Source](https://www.codetriage.com/zhandao/zero-rails_openapi/badges/users.svg)](https://www.codetriage.com/zhandao/zero-rails_openapi)
|
9
|
+
|
10
|
+
Concise DSL for generating OpenAPI Specification 3 (**OAS3**, formerly Swagger3) JSON documentation for Rails application,
|
10
11
|
then you can use Swagger UI 3.2.0+ to show the documentation.
|
11
12
|
|
12
13
|
## Contributing
|
@@ -14,7 +15,7 @@
|
|
14
15
|
**Hi, here is ZhanDao = ▽ =
|
15
16
|
I think it's a very useful tool when you want to write API document clearly.
|
16
17
|
I'm looking forward to your issue and PR, thanks!**
|
17
|
-
|
18
|
+
|
18
19
|
And, if you have any questions, please read the test code first.
|
19
20
|
such as [api DSL](spec/api_info_obj_spec.rb) and [schema Obj](spec/oas_objs/schema_obj_spec.rb).
|
20
21
|
|
@@ -24,6 +25,7 @@
|
|
24
25
|
- [Installation](#installation)
|
25
26
|
- [Configure](#configure)
|
26
27
|
- [Usage - DSL](#usage---dsl)
|
28
|
+
- [Basic DSL](#basic-dsl)
|
27
29
|
- [DSL methods inside `api` and `api_dry`'s block](#dsl-methods-inside-api-and-api_drys-block)
|
28
30
|
- [DSL methods inside `components`'s block](#dsl-methods-inside-componentss-block-code-source)
|
29
31
|
- [Run! - Generate JSON documentation file](#run---generate-json-documentation-file)
|
@@ -41,51 +43,51 @@
|
|
41
43
|
## About OAS
|
42
44
|
|
43
45
|
Everything about OAS3 is on [OpenAPI Specification](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md)
|
44
|
-
|
46
|
+
|
45
47
|
You can getting started from [swagger.io](https://swagger.io/docs/specification/basic-structure/)
|
46
|
-
|
48
|
+
|
47
49
|
**I suggest you should understand OAS3's basic structure at least.**
|
48
|
-
such as component (can help you reuse DSL code, when your apis are used with the
|
50
|
+
such as component (can help you reuse DSL code, when your apis are used with the
|
49
51
|
same data structure).
|
50
52
|
|
51
53
|
## Installation
|
52
54
|
|
53
55
|
Add this line to your Rails's Gemfile:
|
54
|
-
|
56
|
+
|
55
57
|
```ruby
|
56
58
|
gem 'zero-rails_openapi'
|
57
59
|
# or
|
58
60
|
gem 'zero-rails_openapi', github: 'zhandao/zero-rails_openapi'
|
59
61
|
```
|
60
|
-
|
62
|
+
|
61
63
|
And then execute:
|
62
|
-
|
64
|
+
|
63
65
|
$ bundle
|
64
|
-
|
66
|
+
|
65
67
|
Or install it yourself as:
|
66
|
-
|
68
|
+
|
67
69
|
$ gem install zero-rails_openapi
|
68
|
-
|
70
|
+
|
69
71
|
## Configure
|
70
72
|
|
71
73
|
Create an initializer, configure ZRO and define your OpenApi documents.
|
72
|
-
|
74
|
+
|
73
75
|
This is the simplest example:
|
74
|
-
|
76
|
+
|
75
77
|
```ruby
|
76
78
|
# config/initializers/open_api.rb
|
77
79
|
require 'open_api'
|
78
|
-
|
80
|
+
|
79
81
|
OpenApi::Config.tap do |c|
|
80
82
|
# [REQUIRED] The output location where .json doc file will be written to.
|
81
83
|
c.file_output_path = 'public/open_api'
|
82
|
-
|
84
|
+
|
83
85
|
c.open_api_docs = {
|
84
86
|
# The definition of the document `homepage`.
|
85
87
|
homepage: {
|
86
88
|
# [REQUIRED] ZRO will scan all the descendants of base_doc_class, then generate their docs.
|
87
89
|
base_doc_class: Api::V1::BaseController,
|
88
|
-
|
90
|
+
|
89
91
|
# [REQUIRED] OAS Info Object: The section contains API information.
|
90
92
|
info: {
|
91
93
|
# [REQUIRED] The title of the application.
|
@@ -102,14 +104,14 @@
|
|
102
104
|
}
|
103
105
|
end
|
104
106
|
```
|
105
|
-
|
107
|
+
|
106
108
|
In addition to directly using Hash,
|
107
109
|
you can also use DSL to define the document information:
|
108
|
-
|
110
|
+
|
109
111
|
```ruby
|
110
112
|
# config/initializers/open_api.rb
|
111
113
|
require 'open_api'
|
112
|
-
|
114
|
+
|
113
115
|
OpenApi::Config.tap do |c|
|
114
116
|
c.instance_eval do
|
115
117
|
open_api :homepage_api, base_doc_class: ApiDoc
|
@@ -117,7 +119,7 @@
|
|
117
119
|
end
|
118
120
|
end
|
119
121
|
```
|
120
|
-
|
122
|
+
|
121
123
|
For more detailed configuration: [open_api.rb](documentation/examples/open_api.rb)
|
122
124
|
See all the settings you can configure: [config.rb](lib/open_api/config.rb)
|
123
125
|
See all the Document Definition DSL: [config_dsl.rb](lib/open_api/config_dsl.rb)
|
@@ -136,7 +138,7 @@
|
|
136
138
|
### DSL Usage Example
|
137
139
|
|
138
140
|
Here is the simplest usage:
|
139
|
-
|
141
|
+
|
140
142
|
```ruby
|
141
143
|
class Api::ExamplesController < ApiController
|
142
144
|
api :index, 'GET list' do
|
@@ -145,11 +147,11 @@
|
|
145
147
|
end
|
146
148
|
end
|
147
149
|
```
|
148
|
-
|
150
|
+
|
149
151
|
For more example, see [goods_doc.rb](documentation/examples/goods_doc.rb), and
|
150
152
|
[examples_controller.rb](documentation/examples/examples_controller.rb)
|
151
153
|
|
152
|
-
### DSL
|
154
|
+
### Basic DSL ([source code](lib/open_api/dsl.rb))
|
153
155
|
|
154
156
|
#### (1) `route_base` [optional if you're writing DSL in controller]
|
155
157
|
|
@@ -160,9 +162,9 @@
|
|
160
162
|
route_base 'api/v1/examples'
|
161
163
|
```
|
162
164
|
It is optional because `route_base` defaults to `controller_path`.
|
163
|
-
|
164
|
-
[Here's a trick](#trick1---write-the-dsl-somewhere-else): Using `route_base`, you can write the DSL somewhere else
|
165
|
-
to simplify the current controller.
|
165
|
+
|
166
|
+
[Here's a trick](#trick1---write-the-dsl-somewhere-else): Using `route_base`, you can write the DSL somewhere else
|
167
|
+
to simplify the current controller.
|
166
168
|
|
167
169
|
#### (2) `doc_tag` [optional]
|
168
170
|
|
@@ -170,11 +172,11 @@
|
|
170
172
|
# method signature
|
171
173
|
doc_tag(name: nil, desc: '', external_doc_url: nil)
|
172
174
|
# usage
|
173
|
-
doc_tag name: 'ExampleTagName', desc:
|
175
|
+
doc_tag name: 'ExampleTagName', desc: "ExamplesController's APIs"
|
174
176
|
```
|
175
|
-
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)).
|
176
|
-
|
177
|
-
|
177
|
+
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
|
+
|
179
|
+
Tag's name defaults to controller_name. desc and external_doc_url are optional.
|
178
180
|
|
179
181
|
#### (3) `components` [optional]
|
180
182
|
|
@@ -188,7 +190,7 @@
|
|
188
190
|
query! :UidQuery => [ :uid, String, desc: 'uid' ]
|
189
191
|
resp :BadRqResp => [ 'bad request', :json ]
|
190
192
|
end
|
191
|
-
|
193
|
+
|
192
194
|
# to use component
|
193
195
|
api :action, 'summary' do
|
194
196
|
query :doge, :DogSchema # to use a Schema component
|
@@ -196,15 +198,16 @@
|
|
196
198
|
response_ref :BadRqResp # to use a Response component
|
197
199
|
end
|
198
200
|
```
|
199
|
-
Component can be used to simplify your DSL code
|
200
|
-
|
201
|
-
|
202
|
-
|
201
|
+
Component can be used to simplify your DSL code
|
202
|
+
(that is, to refer to the defined Component object by `*_ref` methods).
|
203
|
+
|
204
|
+
Each RefObj is associated with components through component key.
|
205
|
+
We suggest that component keys should be camelized, and must be Symbol.
|
203
206
|
|
204
207
|
#### (4) `api_dry` [optional]
|
205
208
|
|
206
209
|
This method is for DRYing.
|
207
|
-
|
210
|
+
|
208
211
|
```ruby
|
209
212
|
# method signature
|
210
213
|
api_dry(action = :all, desc = '', &block)
|
@@ -215,37 +218,34 @@
|
|
215
218
|
query! #...
|
216
219
|
end
|
217
220
|
```
|
218
|
-
|
221
|
+
|
219
222
|
As you think, the block will be executed to each specified API(action) **firstly**.
|
220
|
-
|
223
|
+
|
221
224
|
#### (5) `api` [required]
|
222
225
|
|
223
|
-
Define the specified API
|
224
|
-
|
226
|
+
Define the specified API
|
227
|
+
(or we could say controller action).
|
228
|
+
|
225
229
|
```ruby
|
226
230
|
# method signature
|
227
|
-
api(action, summary = '', skip: [ ], use: [ ], &block)
|
231
|
+
api(action, summary = '', http: nil, skip: [ ], use: [ ], &block)
|
228
232
|
# usage
|
229
233
|
api :index, '(SUMMARY) this api blah blah ...', # block ...
|
230
234
|
```
|
231
|
-
|
235
|
+
|
232
236
|
`use` and `skip` options: to use or skip the parameters defined in `api_dry`.
|
233
|
-
|
234
|
-
[Note] JBuilder file automatic generator has been removed,
|
235
|
-
If you need this function, please refer to [here](https://github.com/zhandao/zero-rails/tree/master/lib/generators/jubilder/dsl.rb)
|
236
|
-
to implement a lib.
|
237
|
-
|
237
|
+
|
238
238
|
```ruby
|
239
|
-
api :show, 'summary', use: [:id] #
|
239
|
+
api :show, 'summary', use: [:id] # it will only take :id from DRYed result to define the API :show
|
240
240
|
```
|
241
241
|
|
242
242
|
### DSL methods inside [api]() and [api_dry]()'s block
|
243
243
|
|
244
244
|
[source code](lib/open_api/dsl/api_info_obj.rb)
|
245
|
-
|
245
|
+
|
246
246
|
These following methods in the block describe the specified API action: description, valid?,
|
247
247
|
parameters, request body, responses, securities, servers.
|
248
|
-
|
248
|
+
|
249
249
|
(Here corresponds to OAS [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#operationObject))
|
250
250
|
|
251
251
|
#### (1) `this_api_is_invalid!`, its aliases:
|
@@ -261,7 +261,7 @@
|
|
261
261
|
# usage
|
262
262
|
this_api_is_invalid! 'this api is expired!'
|
263
263
|
```
|
264
|
-
|
264
|
+
|
265
265
|
Then `deprecated` of this API will be set to true.
|
266
266
|
|
267
267
|
#### (2) `desc`: description for the current API and its inputs (parameters and request body)
|
@@ -275,9 +275,9 @@
|
|
275
275
|
email: 'desc of the parameter :email'
|
276
276
|
```
|
277
277
|
|
278
|
-
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)),
|
278
|
+
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)),
|
279
279
|
but that will make it long and ugly. We recommend that unite descriptions in this place.
|
280
|
-
|
280
|
+
|
281
281
|
In addition, when you want to dry the same parameters (each with a different description), it will be of great use.
|
282
282
|
|
283
283
|
#### (3) `param` family methods (OAS - [Parameter Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#parameterObject))
|
@@ -285,7 +285,7 @@
|
|
285
285
|
Define the parameters for the API (action).
|
286
286
|
```
|
287
287
|
param
|
288
|
-
param_ref # for reuse component,
|
288
|
+
param_ref # for reuse component,
|
289
289
|
# it links sepcified RefObjs (by component keys) to current parameters.
|
290
290
|
header, path, query, cookie # will pass specified parameter location to `param`
|
291
291
|
header!, path!, query!, cookie! # bang method of above methods
|
@@ -301,22 +301,22 @@
|
|
301
301
|
# `schema_type` is the type of parameter, like: String, Integer (must be a constant)
|
302
302
|
# For more explanation, please click the link below ↓↓↓
|
303
303
|
# method signature
|
304
|
-
param(param_type, param_name, schema_type, is_required,
|
304
|
+
param(param_type, param_name, schema_type, is_required, schema_info = { })
|
305
305
|
# usage
|
306
306
|
param :query, :page, Integer, :req, range: { gt: 0, le: 5 }, desc: 'page'
|
307
|
-
|
308
|
-
|
307
|
+
|
308
|
+
|
309
309
|
# method signature
|
310
310
|
param_ref(component_key, *component_keys) # should pass at least 1 key
|
311
311
|
# usage
|
312
312
|
param_ref :IdPath
|
313
313
|
param_ref :IdPath, :NameQuery, :TokenHeader
|
314
|
-
|
315
|
-
|
314
|
+
|
315
|
+
|
316
316
|
### method signature
|
317
|
-
header(param_name, schema_type = nil,
|
318
|
-
header!(param_name, schema_type = nil,
|
319
|
-
query!(param_name, schema_type = nil,
|
317
|
+
header(param_name, schema_type = nil, **schema_info)
|
318
|
+
header!(param_name, schema_type = nil, **schema_info)
|
319
|
+
query!(param_name, schema_type = nil, **schema_info)
|
320
320
|
# ...
|
321
321
|
### usage
|
322
322
|
header! 'Token', String
|
@@ -324,7 +324,7 @@
|
|
324
324
|
# The same effect as above, but not simple
|
325
325
|
param :query, :readed, Boolean, :req, must_be: true, default: false
|
326
326
|
#
|
327
|
-
# When schema_type is a Object
|
327
|
+
# When schema_type is a Object
|
328
328
|
# (describe by hash, key means prop's name, value means prop's schema_type)
|
329
329
|
query :good, { name: String, price: Float, spec: { size: String, weight: Integer } }, desc: 'good info'
|
330
330
|
# Or you can use `type:` to sign the schema_type, maybe this is clearer for describing object
|
@@ -347,8 +347,8 @@
|
|
347
347
|
query :search_type, String
|
348
348
|
query :search_val, String
|
349
349
|
query! :export, Boolean
|
350
|
-
|
351
|
-
|
350
|
+
|
351
|
+
|
352
352
|
# method signature
|
353
353
|
# `exp_by` (select_example_by): choose the example fields.
|
354
354
|
examples(exp_by = :all, examples_hash)
|
@@ -356,11 +356,11 @@
|
|
356
356
|
# it defines 2 examples by using parameter :id and :name
|
357
357
|
# if pass :all to `exp_by`, keys will be all the parameter's names.
|
358
358
|
examples [:id, :name], {
|
359
|
-
|
360
|
-
|
359
|
+
:right_input => [ 1, 'user'], # == { id: 1, name: 'user' }
|
360
|
+
:wrong_input => [ -1, '' ]
|
361
361
|
}
|
362
362
|
```
|
363
|
-
|
363
|
+
|
364
364
|
[This trick show you how to define combined schema (by using `one_of` ..)](#trick6---combined-schema-one-of--all-of--any-of--not)
|
365
365
|
|
366
366
|
[**>> More About `param` DSL <<**](documentation/parameter.md)
|
@@ -370,7 +370,7 @@
|
|
370
370
|
OpenAPI 3.0 uses the requestBody keyword to distinguish the payload from parameters.
|
371
371
|
```
|
372
372
|
request_body
|
373
|
-
body_ref # for reuse component,
|
373
|
+
body_ref # for reuse component,
|
374
374
|
# it links sepcified RefObjs (by component keys) to current body.
|
375
375
|
body, body! # alias of request_body
|
376
376
|
form, form! # define a multipart/form-data body
|
@@ -398,36 +398,36 @@
|
|
398
398
|
body!(media_type, data: { }, **options)
|
399
399
|
# usage
|
400
400
|
body :json
|
401
|
-
|
402
|
-
|
401
|
+
|
402
|
+
|
403
403
|
# method implement
|
404
404
|
def form data:, **options
|
405
405
|
body :form, data: data, **options
|
406
406
|
end
|
407
407
|
# usage
|
408
408
|
form! data: {
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
409
|
+
name: String,
|
410
|
+
password: String,
|
411
|
+
password_confirmation: String
|
412
|
+
}
|
413
413
|
# advance usage
|
414
414
|
form data: {
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
415
|
+
:name! => { type: String, desc: 'user name' },
|
416
|
+
:password! => { type: String, pattern: /[0-9]{6,10}/, desc: 'password' },
|
417
|
+
# optional
|
418
|
+
:remarks => { type: String, desc: 'remarks' },
|
419
|
+
}, exp_by: %i[ name password ],
|
420
|
+
examples: { # ↓ ↓
|
421
|
+
:right_input => [ 'user1', '123456' ],
|
422
|
+
:wrong_input => [ 'user2', 'abc' ]
|
423
|
+
},
|
424
|
+
desc: 'for creating a user'
|
425
|
+
|
426
|
+
|
427
427
|
# method implement
|
428
|
-
def data name, type = nil,
|
429
|
-
|
430
|
-
form data: { name =>
|
428
|
+
def data name, type = nil, schema_info = { }
|
429
|
+
schema_info[:type] = type if type.present?
|
430
|
+
form data: { name => schema_info }
|
431
431
|
end
|
432
432
|
# usage: please look at the 4th point below
|
433
433
|
|
@@ -436,9 +436,9 @@
|
|
436
436
|
body! media_type, data: data, **options
|
437
437
|
end
|
438
438
|
```
|
439
|
-
|
440
|
-
1. `media_type`: we provide some [mapping](lib/oas_objs/media_type_obj.rb) from symbols to real media-types.
|
441
|
-
2. `
|
439
|
+
|
440
|
+
1. `media_type`: we provide some [mapping](lib/oas_objs/media_type_obj.rb) from symbols to real media-types.
|
441
|
+
2. `schema_info`: as above (see param).
|
442
442
|
3. `exp_by` and `examples`: for the above example, the following has the same effect:
|
443
443
|
```
|
444
444
|
examples: {
|
@@ -459,23 +459,23 @@
|
|
459
459
|
data :param_a!, String
|
460
460
|
data :param_b, Integer
|
461
461
|
# or same as:
|
462
|
-
form
|
463
|
-
form
|
462
|
+
form data: { :param_a! => String }
|
463
|
+
form data: { :param_b => Integer }
|
464
464
|
# will generate: { "param_a": { "type": "string" }, "param_b": { "type": "integer" } } (call it X)
|
465
465
|
# therefore:
|
466
|
-
# "content": { "multipart/form-data":
|
467
|
-
# { "schema": { "type": "object", "properties": { X }, "required": [ "param_a" ] }
|
466
|
+
# "content": { "multipart/form-data":
|
467
|
+
# { "schema": { "type": "object", "properties": { X }, "required": [ "param_a" ] }
|
468
468
|
# }
|
469
469
|
```
|
470
|
-
|
470
|
+
|
471
471
|
#### (5) `response` family methods (OAS - [Response Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#response-object))
|
472
|
-
|
472
|
+
|
473
473
|
Define the responses for the API (action).
|
474
474
|
```
|
475
475
|
response # aliases: `resp` and `error`
|
476
476
|
response_ref
|
477
477
|
```
|
478
|
-
|
478
|
+
|
479
479
|
```ruby
|
480
480
|
# method signature
|
481
481
|
response(code, desc, media_type = nil, data: { }, type: nil)
|
@@ -490,17 +490,17 @@
|
|
490
490
|
# usage
|
491
491
|
response_ref 700 => :AResp, 800 => :BResp
|
492
492
|
```
|
493
|
-
|
494
|
-
**practice:** Automatically generate responses based on the agreed error class. [AutoGenDoc](documentation/examples/auto_gen_doc.rb#L63)
|
495
|
-
|
493
|
+
|
494
|
+
**practice:** Automatically generate responses based on the agreed error class. [AutoGenDoc](documentation/examples/auto_gen_doc.rb#L63)
|
495
|
+
|
496
496
|
#### (6) Authentication and Authorization
|
497
|
-
|
498
|
-
First of all, please make sure that you have read one of the following documents:
|
499
|
-
[OpenApi Auth](https://swagger.io/docs/specification/authentication/)
|
497
|
+
|
498
|
+
First of all, please make sure that you have read one of the following documents:
|
499
|
+
[OpenApi Auth](https://swagger.io/docs/specification/authentication/)
|
500
500
|
or [securitySchemeObject](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securitySchemeObject)
|
501
|
-
|
501
|
+
|
502
502
|
##### Define Security Scheme
|
503
|
-
|
503
|
+
|
504
504
|
Use these DSL in your initializer or `components` block:
|
505
505
|
```
|
506
506
|
security_scheme # alias `auth_scheme`
|
@@ -514,7 +514,7 @@
|
|
514
514
|
security_scheme(scheme_name, other_info)
|
515
515
|
# usage
|
516
516
|
security_scheme :BasicAuth, { type: 'http', scheme: 'basic', desc: 'basic auth' }
|
517
|
-
|
517
|
+
|
518
518
|
# method signature
|
519
519
|
base_auth(scheme_name, other_info = { })
|
520
520
|
bearer_auth(scheme_name, format = 'JWT', other_info = { })
|
@@ -524,16 +524,16 @@
|
|
524
524
|
bearer_auth :Token
|
525
525
|
api_key :ApiKeyAuth, field: 'X-API-Key', in: 'header', desc: 'pass api key to header'
|
526
526
|
```
|
527
|
-
|
527
|
+
|
528
528
|
##### Apply Security
|
529
|
-
|
529
|
+
|
530
530
|
```
|
531
531
|
# In initializer
|
532
532
|
# Global effectiveness
|
533
533
|
global_security_require
|
534
534
|
global_security # alias
|
535
535
|
global_auth # alias
|
536
|
-
|
536
|
+
|
537
537
|
# In `api`'s block
|
538
538
|
# Only valid for the current controller
|
539
539
|
security_require
|
@@ -552,21 +552,21 @@
|
|
552
552
|
```
|
553
553
|
|
554
554
|
#### (7) Overriding Global Servers by `server`
|
555
|
-
|
555
|
+
|
556
556
|
```ruby
|
557
557
|
# method signature
|
558
558
|
server(url, desc: '')
|
559
559
|
# usage
|
560
560
|
server 'http://localhost:3000', desc: 'local'
|
561
561
|
```
|
562
|
-
|
562
|
+
|
563
563
|
### DSL methods inside [components]()'s block ([code source](lib/open_api/dsl/components.rb))
|
564
564
|
|
565
565
|
(Here corresponds to OAS [Components Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#componentsObject))
|
566
566
|
|
567
567
|
Inside `components`'s block,
|
568
568
|
you can use the same DSL as [[DSL methods inside `api` and `api_dry`'s block]](#dsl-methods-inside-api-and-api_drys-block).
|
569
|
-
But there are two differences:
|
569
|
+
But there are two differences:
|
570
570
|
|
571
571
|
(1) Each method needs to pass one more parameter `component_key`
|
572
572
|
(in the first parameter position),
|
@@ -575,7 +575,7 @@
|
|
575
575
|
```ruby
|
576
576
|
query! :UidQuery, :uid, String
|
577
577
|
```
|
578
|
-
This writing is feasible but not recommended,
|
578
|
+
This writing is feasible but not recommended,
|
579
579
|
because component's key and parameter's name seem easy to confuse.
|
580
580
|
The recommended writing is:
|
581
581
|
|
@@ -587,7 +587,7 @@
|
|
587
587
|
|
588
588
|
```ruby
|
589
589
|
# method signature
|
590
|
-
schema(component_key, type = nil,
|
590
|
+
schema(component_key, type = nil, **schema_info)
|
591
591
|
# usage
|
592
592
|
schema :Dog => [ String, desc: 'dogee' ] # <= schema_type is `String`
|
593
593
|
# advance usage
|
@@ -611,22 +611,22 @@
|
|
611
611
|
## Run! - Generate JSON Documentation File
|
612
612
|
|
613
613
|
Use `OpenApi.write_docs`:
|
614
|
-
|
614
|
+
|
615
615
|
```ruby
|
616
616
|
# initializer
|
617
617
|
OpenApi.write_docs generate_files: !Rails.env.production?
|
618
|
-
|
618
|
+
|
619
619
|
# or run directly in console
|
620
620
|
OpenApi.write_docs # will generate json doc files
|
621
621
|
```
|
622
|
-
|
622
|
+
|
623
623
|
Then the JSON files will be written to the directories you set. (Each API a file.)
|
624
624
|
|
625
625
|
## Use Swagger UI(very beautiful web page) to show your Documentation
|
626
626
|
|
627
|
-
Download [Swagger UI](https://github.com/swagger-api/swagger-ui) (version >= 2.3.0 support the OAS3)
|
628
|
-
to your project,
|
629
|
-
change the default JSON file path(url) in index.html.
|
627
|
+
Download [Swagger UI](https://github.com/swagger-api/swagger-ui) (version >= 2.3.0 support the OAS3)
|
628
|
+
to your project,
|
629
|
+
change the default JSON file path(url) in index.html.
|
630
630
|
In order to use it, you may have to enable CORS, [see](https://github.com/swagger-api/swagger-ui#cors-support)
|
631
631
|
|
632
632
|
## Tricks
|
@@ -636,39 +636,39 @@
|
|
636
636
|
Does your documentation take too many lines?
|
637
637
|
Do you want to separate documentation from business controller to simplify both?
|
638
638
|
Very easy! Just follow
|
639
|
-
|
639
|
+
|
640
640
|
```ruby
|
641
641
|
# config/initializers/open_api.rb
|
642
642
|
# in your configuration
|
643
643
|
base_doc_class: ApiDoc
|
644
|
-
|
644
|
+
|
645
645
|
# app/api_doc/api_doc.rb
|
646
646
|
require 'open_api/dsl'
|
647
|
-
|
647
|
+
|
648
648
|
class ApiDoc < Object
|
649
649
|
include OpenApi::DSL
|
650
650
|
end
|
651
|
-
|
651
|
+
|
652
652
|
# app/api_doc/v1/examples_doc.rb
|
653
653
|
class V1::ExamplesDoc < ApiDoc
|
654
654
|
route_base 'api/v1/examples'
|
655
|
-
|
655
|
+
|
656
656
|
api :index do
|
657
657
|
# ...
|
658
658
|
end
|
659
659
|
end
|
660
660
|
```
|
661
|
-
|
661
|
+
|
662
662
|
Notes: file name ends in `_doc.rb` by default, but you can change via `Config.doc_location`
|
663
663
|
(it should be file paths, defaults to `./app/**/*_doc.rb`).
|
664
664
|
|
665
665
|
### Trick2 - Global DRYing
|
666
666
|
|
667
667
|
Method `api_dry` is for DRY but its scope is limited to the current controller.
|
668
|
-
|
668
|
+
|
669
669
|
I have no idea of best practices, But you can look at this [file](documentation/examples/auto_gen_doc.rb).
|
670
670
|
The implementation of the file is: do `api_dry` when inherits the base controller inside `inherited` method.
|
671
|
-
|
671
|
+
|
672
672
|
You can use `sort` to specify the order of parameters.
|
673
673
|
|
674
674
|
### Trick3 - Auto Generate Description
|
@@ -677,19 +677,19 @@
|
|
677
677
|
desc 'api desc',
|
678
678
|
search_type!: 'search field, allows:<br/>'
|
679
679
|
query :search_type, String, enum: %w[name creator category price]
|
680
|
-
|
680
|
+
|
681
681
|
# or
|
682
|
-
|
682
|
+
|
683
683
|
query :search_type, String, desc!: 'search field, allows:<br/>',
|
684
684
|
enum: %w[name creator category price]
|
685
685
|
```
|
686
|
-
|
686
|
+
|
687
687
|
Notice `!` use (`search_type!`, `desc!`), it tells ZRO to append
|
688
688
|
information that analyzed from definitions (enum, must_be ..) to description automatically.
|
689
|
-
|
690
|
-
Any one of above will generate:
|
689
|
+
|
690
|
+
Any one of above will generate:
|
691
691
|
> search field, allows:<br/>1/ name<br/>2/ creator,<br/>3/ category<br/>4/ price<br/>
|
692
|
-
|
692
|
+
|
693
693
|
You can also use Hash to define `enum`:
|
694
694
|
```ruby
|
695
695
|
query :view, String, desc: 'allows values<br/>', enum!: {
|
@@ -708,27 +708,27 @@
|
|
708
708
|
```ruby
|
709
709
|
api :index, 'desc', skip: [ :Token ]
|
710
710
|
```
|
711
|
-
|
711
|
+
|
712
712
|
Look at this [file](documentation/examples/goods_doc.rb) to learn more.
|
713
713
|
|
714
714
|
### Trick5 - Auto Generate index/show Actions's Response-Types Based on DB Schema
|
715
715
|
|
716
716
|
Use method `load_schema` in `api_dry`.
|
717
|
-
|
717
|
+
|
718
718
|
See this [file](documentation/examples/auto_gen_doc.rb#L51) for uasge information.
|
719
719
|
|
720
720
|
### Trick6 - Combined Schema (one_of / all_of / any_of / not)
|
721
721
|
|
722
722
|
```ruby
|
723
723
|
query :combination, one_of: [ :GoodSchema, String, { type: Integer, desc: 'integer input' } ]
|
724
|
-
|
725
|
-
form
|
724
|
+
|
725
|
+
form data: {
|
726
726
|
:combination_in_form => { any_of: [ Integer, String ] }
|
727
727
|
}
|
728
|
-
|
728
|
+
|
729
729
|
schema :PetSchema => [ not: [ Integer, Boolean ] ]
|
730
730
|
```
|
731
|
-
|
731
|
+
|
732
732
|
OAS: [link1](https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/),
|
733
733
|
[link2](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject)
|
734
734
|
|
@@ -737,7 +737,7 @@
|
|
737
737
|
- **You wrote document of the current API, but not find in the generated json file?**
|
738
738
|
Check your routing settings.
|
739
739
|
- **Undefine method `match?`**
|
740
|
-
Monkey patches for `String` and `Symbol`:
|
740
|
+
Monkey patches for `String` and `Symbol`:
|
741
741
|
```ruby
|
742
742
|
class String # Symbol
|
743
743
|
def match?(pattern); !match(pattern).nil? end
|
@@ -745,7 +745,7 @@
|
|
745
745
|
```
|
746
746
|
- **Report error when require `routes.rb`?***
|
747
747
|
1. Run `rails routes`.
|
748
|
-
2. Copy the output to a file, for example `config/routes.txt`.
|
748
|
+
2. Copy the output to a file, for example `config/routes.txt`.
|
749
749
|
Ignore the file `config/routes.txt`.
|
750
750
|
3. Put `c.rails_routes_file = 'config/routes.txt'` to your ZRO config.
|
751
751
|
|
@@ -753,10 +753,10 @@
|
|
753
753
|
## About `OpenApi.docs` and `OpenApi.routes_index`
|
754
754
|
|
755
755
|
After `OpenApi.write_docs`, the above two module variables will be generated.
|
756
|
-
|
756
|
+
|
757
757
|
`OpenApi.docs`: A Hash with API names as keys, and documents of each APIs as values.
|
758
758
|
documents are instances of ActiveSupport::HashWithIndifferentAccess.
|
759
|
-
|
759
|
+
|
760
760
|
`OpenApi.routes_index`: Inverted index of controller path to API name mappings.
|
761
761
|
Like: `{ 'api/v1/examples' => :homepage_api }`
|
762
762
|
It's useful when you want to look up a document based on a controller and do something.
|
@@ -764,7 +764,7 @@
|
|
764
764
|
## Development
|
765
765
|
|
766
766
|
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.
|
767
|
-
|
767
|
+
|
768
768
|
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).
|
769
769
|
|
770
770
|
## License
|