zero-rails_openapi 1.7.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2c36d4739cd18b900e08cfa519027be7708db2c0
4
- data.tar.gz: 190d31752d67ef9d7604b13dff821babd0028021
3
+ metadata.gz: 275729646bbe765cc93239a7635934be22850304
4
+ data.tar.gz: 48e99273f58abd736763251c7eeccdde63d1b4a6
5
5
  SHA512:
6
- metadata.gz: 8b2b5384e8232e85f68859142d503377c8dea9a4688f51af9813e50bc7121c9f217878b388881a28026b689f651d06bc14ab096f283948aad3d7f8e7c25954bd
7
- data.tar.gz: 6ccd82ee0b02dfaf6c3c2df7b026cc515ca63471db87b4610eaead41c55b3b59d60198c2fa4ae15c0013db2616252e0c08f04e8d98e41b022d7c994fd5de3383
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
- [Need Help](https://github.com/zhandao/zero-rails_openapi/issues/14)
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 - DSL](#usage---dsl)
37
- - [Basic DSL](#basic-dsl)
38
- - [route_base](#1-route_base-optional-if-youre-writing-dsl-in-controller)
39
- - [doc_tag](#2-doc_tag-optional)
40
- - [components](#3-components-optional)
41
- - [api_dry](#4-api_dry-optional)
42
- - [api](#5-api-required)
43
- - [DSL methods inside `api` and `api_dry`'s block](#dsl-methods-inside-api-and-api_drys-block)
44
- - [this_api_is_invalid!](#1-this_api_is_invalid-its-aliases)
45
- - [desc](#2-desc-description-for-the-current-api-and-its-inputs-parameters-and-request-body)
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
- - [DSL methods inside `components`'s block](#dsl-methods-inside-componentss-block-code-source)
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.tap do |c|
104
- # [REQUIRED] The output location where .json doc file will be written to.
105
- c.file_output_path = 'public/open_api'
106
-
107
- c.open_api_docs = {
108
- # The definition of the document `homepage`.
109
- homepage: {
110
- # [REQUIRED] ZRO will scan all the descendants of base_doc_classes, then generate their docs.
111
- base_doc_classes: [Api::V1::BaseController],
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
- In addition to directly using Hash,
131
- you can also use DSL to define the document information:
132
-
133
- ```ruby
134
- # config/initializers/open_api.rb
135
- require 'open_api'
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
- OpenApi::Config.tap do |c|
138
- c.file_output_path = 'public/open_api'
122
+ ### Part 2: config (DSL) for generating OpenApi info
139
123
 
140
- c.instance_eval do
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
- For more detailed configuration: [open_api.rb](documentation/examples/open_api.rb)
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
- ## Usage - DSL
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` to your base class (which is for writing docs), for example:
132
+ ### First of all, `include OpenApi::DSL` in your base class (which is for writing spec):
154
133
 
155
- ```ruby
156
- # app/controllers/api/api_controller.rb
157
- class ApiController < ActionController::API
158
- include OpenApi::DSL
159
- end
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#, desc: 'page, greater than 1', range: { ge: 1 }, dft: 1
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
- For more example, see [goods_doc.rb](documentation/examples/goods_doc.rb), and
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
- ### Basic DSL ([source code](lib/open_api/dsl.rb))
157
+ [source code](lib/open_api/dsl.rb)
180
158
 
181
- #### (1) `route_base` [optional if you're writing DSL in controller]
159
+ #### (1) `route_base` [required if you're not writing DSL in controller]
182
160
 
183
161
  ```ruby
184
- # method signature
185
- route_base(path)
186
- # usage
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
- [Here's a trick](#trick1---write-the-dsl-somewhere-else): Using `route_base`, you can write the DSL somewhere else
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
- # method signature
198
- doc_tag(name: nil, desc: '', external_doc_url: nil)
199
- # usage
200
- doc_tag name: 'ExampleTagName', desc: "ExamplesController's APIs"
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. desc and external_doc_url are optional.
181
+ Tag's name defaults to controller_name.
205
182
 
206
183
  #### (3) `components` [optional]
207
184
 
208
185
  ```ruby
209
- # method signature
186
+ # ** Method Signature
210
187
  components(&block)
211
- # usage
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
- resp :BadRqResp => [ 'bad request', :json ]
193
+ response :BadRqResp => [ 'bad request', :json ]
217
194
  end
218
195
 
219
196
  # to use component
220
- api :action, 'summary' do
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
- #### (4) `api_dry` [optional]
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
- # method signature
238
- api_dry(action = :all, desc = '', &block)
239
- # usage
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
- As you think, the block will be executed to each specified API(action) **firstly**.
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 :show, 'summary', use: [:id] # it will only take :id from DRYed result to define the API :show
243
+ api :index do
244
+ dry
245
+ end
264
246
  ```
265
247
 
266
- ### DSL methods inside [api]() and [api_dry]()'s block
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/api_info_obj.rb)
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, servers.
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
- # method signature
284
- this_api_is_invalid!(explain = '')
285
- # usage
286
- this_api_is_invalid! 'this api is expired!'
265
+ # ** Method Signature
266
+ this_api_is_invalid!(*)
267
+ # ** Usage
268
+ this_api_is_invalid! 'cause old version'
287
269
  ```
288
270
 
289
- Then `deprecated` of this API will be set to true.
271
+ After that, `deprecated` field of this API will be set to true.
290
272
 
291
- #### (2) `desc`: description for the current API and its inputs (parameters and request body)
273
+ #### (2) `desc`: description for the current API
292
274
 
293
275
  ```ruby
294
- # method signature
295
- desc(desc, param_descs = { })
296
- # usage
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
- Define the parameters for the API (action).
284
+ To define parameter for APIs.
310
285
  ```
311
- param
312
- param_ref # for reuse component,
313
- # it links sepcified RefObjs (by component keys) to current parameters.
314
- header, path, query, cookie # will pass specified parameter location to `param`
315
- header!, path!, query!, cookie! # bang method of above methods
316
- do_* by: { parameter_definations } # batch definition parameters, such as do_path, do_query
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, so without `!` means optional.**
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
- # `param_type` just is the location of parameter, like: query, path
325
- # `schema_type` is the type of parameter, like: String, Integer (must be a constant)
326
- # For more explanation, please click the link below ↓↓↓
327
- # method signature
328
- param(param_type, param_name, schema_type, is_required, schema_info = { })
329
- # usage
330
- param :query, :page, Integer, :req, range: { gt: 0, le: 5 }, desc: 'page'
331
-
332
-
333
- # method signature
334
- param_ref(component_key, *component_keys) # should pass at least 1 key
335
- # usage
336
- param_ref :IdPath
337
- param_ref :IdPath, :NameQuery, :TokenHeader
338
-
339
-
340
- ### method signature
341
- header(param_name, schema_type = nil, **schema_info)
342
- header!(param_name, schema_type = nil, **schema_info)
343
- query!(param_name, schema_type = nil, **schema_info)
344
- # ...
345
- ### usage
346
- header! 'Token', String
347
- query! :readed, Boolean, must_be: true, default: false
348
- # The same effect as above, but not simple
349
- param :query, :readed, Boolean, :req, must_be: true, default: false
350
- #
351
- # When schema_type is a Object
352
- # (describe by hash, key means prop's name, value means prop's schema_type)
353
- query :good, { name: String, price: Float, spec: { size: String, weight: Integer } }, desc: 'good info'
354
- # Or you can use `type:` to sign the schema_type, maybe this is clearer for describing object
355
- query :good, type: { name: String, price: Float, spec: { size: String, weight: Integer } }, desc: 'good info'
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, but a little bit repetitive
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
- # method signature
377
- # `exp_by` (select_example_by): choose the example fields.
378
- examples(exp_by = :all, examples_hash)
379
- # usage
380
- # it defines 2 examples by using parameter :id and :name
381
- # if pass :all to `exp_by`, keys will be all the parameter's names.
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
- :right_input => [ 1, 'user'], # == { id: 1, name: 'user' }
384
- :wrong_input => [ -1, '' ]
349
+ right_input: [ 1, 'user' ],
350
+ wrong_input: [ 2, 'resu' ]
385
351
  }
386
352
  ```
387
353
 
388
- [This trick show you how to define combined schema (by using `one_of` ..)](#trick6---combined-schema-one-of--all-of--any-of--not)
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
- [**>> More About `param` DSL <<**](documentation/parameter.md)
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 # for reuse component,
398
- # it links sepcified RefObjs (by component keys) to current body.
399
- body, body! # alias of request_body
400
- form, form! # define a multipart/form-data body
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
- # method signature
408
- request_body(required, media_type, data: { }, **options)
409
- # usage
410
- # (1) `data` contains all the attributes required by this request body.
411
- # (2) `param_name!` means it is required, otherwise without '!' means optional.
412
- request_body :opt, :form, data: { id!: Integer, name: { type: String, desc: 'name' } }, desc: 'form-data'
413
-
414
-
415
- # method signature
416
- body_ref(component_key)
417
- # usage
418
- body_ref :UpdateDogeBody
419
-
420
-
421
- # method signature
422
- body!(media_type, data: { }, **options)
423
- # usage
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 implement
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
- # usage
406
+ # ** Usage
432
407
  form! data: {
433
- name: String,
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
- # about `file`
459
- def file! media_type, data: { type: File }, **options
460
- body! media_type, data: data, **options
461
- end
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
- 1. `media_type`: we provide some [mapping](lib/oas_objs/media_type_obj.rb) from symbols to real media-types.
465
- 2. `schema_info`: as above (see param).
466
- 3. `exp_by` and `examples`: for the above example, the following has the same effect:
467
- ```
468
- examples: {
469
- :right_input => { name: 'user1', password: '123456' },
470
- :wrong_input => { name: 'user2', password: 'abc' }
471
- }
472
- ```
473
- 4. *[IMPORTANT]* Each request bodies you declared will **FUSION** together. <a name="fusion"></a>
474
- (1) Media-Types will be merged to `requestBody["content"]`
475
- ```ruby
476
- form data: { }, desc: 'desc'
477
- body :json, data: { }, desc: 'desc'
478
- # will generate: "content": { "multipart/form-data": { }, "application/json": { } }
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
- Define the responses for the API (action).
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
- # method signature
505
- response(code, desc, media_type = nil, data: { }, type: nil)
506
- # usage
507
- resp 200, 'json response', :json, data: { name: 'test' }
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
- # method signature
513
- response_ref(code_compkey_hash)
514
- # usage
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
- To define callbacks, you can use `callback` method:
486
+ `callback` method is for defining callbacks.
541
487
  ```ruby
542
- # method signature
543
- callback(event_name, http_method, callback_url, &block)
544
- # usage
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
- # method signature
577
- security_scheme(scheme_name, other_info)
578
- # usage
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
- # method signature
582
- base_auth(scheme_name, other_info = { })
583
- bearer_auth(scheme_name, format = 'JWT', other_info = { })
584
- api_key(scheme_name, field:, in:, **other_info)
585
- # usage
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
- # In initializer
595
- # Global effectiveness
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
- # In `api`'s block
601
- # Only valid for the current controller
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
- # method signature
610
- security_require(scheme_name, scopes: [ ])
611
- # usage
547
+ # ** Method Signature
548
+ security_require scheme_name, scopes: [ ]
549
+ # ** Usage
612
550
  global_auth :Token
613
- need_auth :Token
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
- # method signature
621
- server(url, desc: '')
622
- # usage
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
- ### DSL methods inside [components]()'s block ([code source](lib/open_api/dsl/components.rb))
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
- (Here corresponds to OAS [Components Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#componentsObject))
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 DSL as [[DSL methods inside `api` and `api_dry`'s block]](#dsl-methods-inside-api-and-api_drys-block).
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
- ```ruby
639
- query! :UidQuery, :uid, String
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 => [:uid, String]
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
- # method signature
653
- schema(component_key, type = nil, **schema_info)
654
- # usage
655
- schema :Dog => [ String, desc: 'dogee' ] # <= schema_type is `String`
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
- id!: Integer,
660
- name: { type: String, must_be: 'name', desc: 'name' }
661
- }, # <= this hash is schema type[1]
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 (unrecommended)
666
- schema :Dog, { id!: Integer, name: String }, dft: { id: 1, name: 'pet' }, desc: 'dogee'
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 read the db schema to generate the component.
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
- [1] see: [Type](documentation/parameter.md#type-schema_type)
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
- # initializer
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](documentation/examples/auto_gen_doc.rb).
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 'api desc',
747
- search_type!: 'search field, allows:<br/>'
748
- query :search_type, String, enum: %w[name creator category price]
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-OpenApi project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).
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).