zero-rails_openapi 1.4.0 → 1.4.1

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: cc28a19288b67c33764363217945eabe353cbe19
4
- data.tar.gz: 383973acb33b8dbbf4e0706e3854aadd252709a1
3
+ metadata.gz: fab58d6a912611eb51d9d86bc69401c5feb70f06
4
+ data.tar.gz: 2aa24ae7d92823d075cbb21acf09949e365d13ab
5
5
  SHA512:
6
- metadata.gz: c599c44d70844213307c8c00e3aac227776df6446236fde17cb021468187ac286bebfae40a82bc316ce553511972b74d72c838f0453548762628b5ed676e4581
7
- data.tar.gz: 9637974d052bfa81702bd379034454a5a85fa20b2a86f2f74f0f117585f03268a5b7f52563f9ddb69e2657519ade1ba9e20c4c8595efb4a5fb0b4d24d7283e18
6
+ metadata.gz: c321e853c95bad0cc5324c9719b3e610c54b2bd4bb18190b2876d091a115b3d90f3b6450645684606ae295c230ab700bca3fa7461fc40a057753376ab6651a02
7
+ data.tar.gz: 4e273a9871cd4e8078bad7cc56a7c6b5e6e40a26825f00e57cc28783d61cf49d7557829b76b7a55e6c3fd3297efc0b1bd124a6237685c4002599812ce55814bb
data/CHANGELOG.md ADDED
@@ -0,0 +1,74 @@
1
+ # Version Changelog
2
+
3
+
4
+ ## [1.4.1] - 2017/12/6 - [view diff](https://github.com/zhandao/zero-rails_openapi/compare/v1.4.0...v1.4.1)
5
+
6
+ ### Feature
7
+
8
+ 1. Pass a ActiveRecord class constant to the `schema`,
9
+ it will automatically read the db schema to generate the component.
10
+
11
+ ### Fixed
12
+
13
+ 1. Fix: Components defined in the controller overwrite the ones defined in the configuration.
14
+
15
+ ### Changed
16
+
17
+ 1. Remove JBuilder automatic generator.
18
+ 2. Refactoring based on CodeClimate.
19
+ 3. Rename `CtrlInfoObj` to `Components`.
20
+
21
+ ### Added
22
+
23
+ 1. Update README.
24
+ 2. Add CHANGELOG.
25
+ 3. `doc_location` can be configured.
26
+
27
+ ## [1.4.0] - 2017/12/3 - [view diff](https://github.com/zhandao/zero-rails_openapi/compare/v1.3.3...v1.4.0)
28
+
29
+ ### Fixed
30
+
31
+ 1. Fix controller's require question in `generate_docs`.
32
+
33
+ ### Feature
34
+
35
+ 1. Support CombinedSchema, like `one_of`, `any_of`..
36
+ 2. Authentication and Authorization DSL, for Defining Security Scheme and Applying Security.
37
+ 3. The ability to identify multi HTTP verbs.
38
+ 4. Support read files to get routes information. (Config.rails_routes_file)
39
+
40
+ ### Changed
41
+
42
+ 1. **[IMPORTANT]** DSL `open_api` => `api`.
43
+ 2. Config.register_docs => Config.open_api_docs.
44
+ 3. Document Definition DSL `api` => `open_api`.
45
+ 4. Use module instance variables instead of global variables.
46
+ 5. Is refactoring based on `rubocop` by hand.
47
+
48
+ ### Added
49
+
50
+ 1. Also support `api :name, type: String`.
51
+ (You have to write this before `api :name, String`)
52
+ 2. Support designated http method in `api`.
53
+ 3. The completion of the basic README.
54
+
55
+ ## [1.3.2 & 1.3.3] - 2017/11/10,21 - [view diff](https://github.com/zhandao/zero-rails_openapi/compare/v1.3.1...v1.3.3)
56
+
57
+ ### Feature
58
+
59
+ 1. Document Definition DSL.
60
+ 2. Parameter `order`:
61
+ Support to use `sort` to specify the order in which parameters are arranged.
62
+ This is useful when you dry your DSL.
63
+ 3. Parameter `examples`.
64
+
65
+ ### Added
66
+
67
+ 1. Rewrote README.
68
+
69
+ ## [1.3.1] - 2017/11/5 - [view diff](https://github.com/zhandao/zero-rails_openapi/compare/v1.3.0...v1.3.1)
70
+
71
+ 1. Refactoring based on bbatsov and Airbnb's style guide, more readable.
72
+ 2. Support response override by using `override_response`.
73
+ 3. Separate `apis_set` into `apis_tag` and `components`.
74
+ 4. Support simplify param DSL with `do_* by: { }` method.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- zero-rails_openapi (1.4.0)
4
+ zero-rails_openapi (1.4.1)
5
5
  activesupport (>= 3)
6
6
  rails (>= 3)
7
7
 
@@ -48,29 +48,27 @@ GEM
48
48
  arel (8.0.0)
49
49
  builder (3.2.3)
50
50
  concurrent-ruby (1.0.5)
51
- crass (1.0.2)
51
+ crass (1.0.3)
52
52
  diff-lcs (1.3)
53
53
  erubi (1.7.0)
54
54
  globalid (0.4.1)
55
55
  activesupport (>= 4.2.0)
56
- i18n (0.9.0)
56
+ i18n (0.9.1)
57
57
  concurrent-ruby (~> 1.0)
58
58
  loofah (2.1.1)
59
59
  crass (~> 1.0.2)
60
60
  nokogiri (>= 1.5.9)
61
- mail (2.6.6)
62
- mime-types (>= 1.16, < 4)
61
+ mail (2.7.0)
62
+ mini_mime (>= 0.1.1)
63
63
  method_source (0.9.0)
64
- mime-types (3.1)
65
- mime-types-data (~> 3.2015)
66
- mime-types-data (3.2016.0521)
64
+ mini_mime (1.0.0)
67
65
  mini_portile2 (2.3.0)
68
66
  minitest (5.10.3)
69
67
  nio4r (2.1.0)
70
68
  nokogiri (1.8.1)
71
69
  mini_portile2 (~> 2.3.0)
72
70
  rack (2.0.3)
73
- rack-test (0.7.0)
71
+ rack-test (0.8.2)
74
72
  rack (>= 1.0, < 3)
75
73
  rails (5.1.4)
76
74
  actioncable (= 5.1.4)
@@ -122,7 +120,7 @@ GEM
122
120
  thread_safe (~> 0.1)
123
121
  websocket-driver (0.6.5)
124
122
  websocket-extensions (>= 0.1.0)
125
- websocket-extensions (0.1.2)
123
+ websocket-extensions (0.1.3)
126
124
 
127
125
  PLATFORMS
128
126
  ruby
data/README.md CHANGED
@@ -2,13 +2,14 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/zero-rails_openapi.svg)](https://badge.fury.io/rb/zero-rails_openapi)
4
4
  [![Build Status](https://travis-ci.org/zhandao/zero-rails_openapi.svg?branch=master)](https://travis-ci.org/zhandao/zero-rails_openapi)
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/471fd60f6eb7b019ceed/maintainability)](https://codeclimate.com/github/zhandao/zero-rails_openapi/maintainability)
5
6
 
6
- Provide concise DSL for generating the OpenAPI Specification 3 (**OAS3**, formerly Swagger3) documentation JSON file for Rails application,
7
+ Concise DSL for generating OpenAPI Specification 3 (**OAS3**, formerly Swagger3) JSON documentation for Rails application,
7
8
  then you can use Swagger UI 3.2.0+ to show the documentation.
8
9
 
9
10
  ## Contributing
10
11
 
11
- **Hi, here is ZhanDao = ▽ =
12
+ **Hi, here is ZhanDao = ▽ =
12
13
  I think it's a very useful tool when you want to write API document clearly.
13
14
  I'm looking forward to your issue and PR, thanks!**
14
15
 
@@ -18,19 +19,19 @@
18
19
  - [Installation](#installation)
19
20
  - [Configure](#configure)
20
21
  - [Usage - DSL](#usage---dsl)
21
- - [DSL methods inside `open_api` and `api_dry`'s block](#dsl-methods-inside-open_api-and-api_drys-block)
22
- - [DSL methods inside `components`'s block](#dsl-methods-inside-componentss-block-code-source-ctrlinfoobj-)
22
+ - [DSL methods inside `api` and `api_dry`'s block](#dsl-methods-inside-api-and-api_drys-block)
23
+ - [DSL methods inside `components`'s block](#dsl-methods-inside-componentss-block-code-source)
23
24
  - [Usage - Generate JSON documentation file](#usage---generate-json-documentation-file)
24
25
  - [Usage - Use Swagger UI(very beautiful web page) to show your Documentation](#usage---use-swagger-uivery-beautiful-web-page-to-show-your-documentation)
25
26
  - [Tricks](#tricks)
26
27
  - [Write DSL somewhere else](#trick1---write-the-dsl-somewhere-else)
27
28
  - [Global DRYing](#trick2---global-drying)
28
29
  - [Auto generate description](#trick3---auto-generate-description)
29
- - [Skip or Use parameters define in api_dry](#trick4---skip-or-use-parameters-define-in-api_dry)
30
+ - [Skip or Use parameters define in `api_dry`](#trick4---skip-or-use-parameters-define-in-api_dry)
30
31
  - [Atuo Generate index/show Actions's Responses Based on DB Schema](#trick5---auto-generate-indexshow-actionss-response-types-based-on-db-schema)
31
- - [Combined Schema (oneOf / allOf / anyOf / not)]()
32
+ - [Combined Schema (one_of / all_of / any_of / not)](#trick6---combined-schema-one_of--all_of--any_of--not)
32
33
  - [Troubleshooting](#troubleshooting)
33
- - [About `OpenApi.docs` and `OpenApi.paths_index`]()
34
+ - [About `OpenApi.docs` and `OpenApi.paths_index`](#about-openapidocs-and-openapipaths_index)
34
35
 
35
36
  ## About OAS
36
37
 
@@ -38,7 +39,7 @@
38
39
 
39
40
  You can getting started from [swagger.io](https://swagger.io/docs/specification/basic-structure/)
40
41
 
41
- **I suggest you should understand OAS3's basic structure at least.**
42
+ **I suggest you should understand OAS3's basic structure at least.**
42
43
  such as component (can help you reuse DSL code, when your apis are used with the
43
44
  same data structure).
44
45
 
@@ -62,9 +63,9 @@
62
63
 
63
64
  ## Configure
64
65
 
65
- Create an initializer, configure ZRO and define your APIs.
66
+ Create an initializer, configure ZRO and define your OpenApi documents.
66
67
 
67
- This is the simplest configuration example:
68
+ This is the simplest example:
68
69
 
69
70
  ```ruby
70
71
  # config/initializers/open_api.rb
@@ -75,7 +76,8 @@
75
76
  c.file_output_path = 'public/open_api'
76
77
 
77
78
  c.open_api_docs = {
78
- homepage_api: {
79
+ # The definition of the document `homepage`.
80
+ homepage: {
79
81
  # [REQUIRED] ZRO will scan all the descendants of root_controller, then generate their docs.
80
82
  root_controller: Api::V1::BaseController,
81
83
 
@@ -95,10 +97,9 @@
95
97
  }
96
98
  end
97
99
  ```
98
- The following global configuration and component of OAS are allow to be set in the initializer:
99
- Server Object / Security Scheme Object / Security Requirement Object ...
100
100
 
101
- In addition to direct use of Hash, you can also use Config DSL to configure:
101
+ In addition to directly using Hash,
102
+ you can also use DSL to define the document information:
102
103
 
103
104
  ```ruby
104
105
  # config/initializers/open_api.rb
@@ -114,11 +115,11 @@
114
115
 
115
116
  For more detailed configuration: [open_api.rb](documentation/examples/open_api.rb)
116
117
  See all the settings you can configure: [config.rb](lib/open_api/config.rb)
117
- See all the Config DSL: [config_dsl.rb](lib/open_api/config_dsl.rb)
118
+ See all the Document Definition DSL: [config_dsl.rb](lib/open_api/config_dsl.rb)
118
119
 
119
120
  ## Usage - DSL
120
121
 
121
- ### First of all, include DSL to your base controller (which is for writing docs), for example:
122
+ ### First of all, `include OpenApi::DSL` to your base class (which is for writing docs), for example:
122
123
 
123
124
  ```ruby
124
125
  # app/controllers/api/api_controller.rb
@@ -143,9 +144,9 @@
143
144
  For more example, see [goods_doc.rb](documentation/examples/goods_doc.rb), and
144
145
  [examples_controller.rb](documentation/examples/examples_controller.rb)
145
146
 
146
- ### DSL methods of controller ([source code](lib/open_api/dsl.rb))
147
+ ### DSL as class methods ([source code](lib/open_api/dsl.rb))
147
148
 
148
- #### (1) `ctrl_path` (controller path) [optional]
149
+ #### (1) `ctrl_path` (controller path) [optional if you're writing DSL in controller]
149
150
 
150
151
  ```ruby
151
152
  # method signature
@@ -218,16 +219,17 @@
218
219
 
219
220
  ```ruby
220
221
  # method signature
221
- api(action, summary = '', builder: nil, skip: [ ], use: [ ], &block)
222
+ api(action, summary = '', skip: [ ], use: [ ], &block)
222
223
  # usage
223
- api :index, '(SUMMARY) this api blah blah ...', builder: :index # block ...
224
+ api :index, '(SUMMARY) this api blah blah ...', # block ...
224
225
  ```
225
- If you pass `builder`, and `generate_jbuilder_file` is set to `true` (in your initializer),
226
- ZRO will generate JBuilder file by using specified template called `index`.
227
- About template settings, see: [open_api.rb](documentation/examples/open_api.rb)
228
226
 
229
227
  `use` and `skip` options: to use or skip the parameters defined in `api_dry`.
230
228
 
229
+ [Note] JBuilder file automatic generator has been removed,
230
+ If you need this function, please refer to [here](https://github.com/zhandao/zero-rails/tree/master/lib/generators/jubilder/dsl.rb)
231
+ to implement a lib.
232
+
231
233
  ```ruby
232
234
  api :show, 'summary', use: [:id] # => it will only take :id from DRYed result.
233
235
  ```
@@ -354,7 +356,7 @@
354
356
  }
355
357
  ```
356
358
 
357
- [This trick show you how to define combined schema (by using `one_of` ..)]()
359
+ [This trick show you how to define combined schema (by using `one_of` ..)](#trick6---combined-schema-one-of--all-of--any-of--not)
358
360
 
359
361
  [**>> More About `param` DSL <<**](documentation/parameter.md)
360
362
 
@@ -535,27 +537,34 @@
535
537
  server 'http://localhost:3000', 'local'
536
538
  ```
537
539
 
538
- ### DSL methods inside [components]()'s block ([code source](lib/open_api/dsl/ctrl_info_obj.rb):: CtrlInfoObj )
540
+ ### DSL methods inside [components]()'s block ([code source](lib/open_api/dsl/components.rb))
539
541
 
540
542
  (Here corresponds to OAS [Components Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#componentsObject))
541
543
 
542
- These methods in the block describe reusable components that you wanna use to define
543
- parameter, response, request body and schema.
544
+ Inside `components`'s block,
545
+ you can use the same DSL as [[DSL methods inside `api` and `api_dry`'s block]](#dsl-methods-inside-api-and-api_drys-block).
546
+ But there are two differences:
547
+
548
+ (1) Each method needs to pass one more parameter `component_key`
549
+ (in the first parameter position),
550
+ this will be used as the reference name for the component.
544
551
 
545
552
  ```ruby
546
553
  query! :UidQuery, :uid, String
547
554
  ```
548
555
  This writing is feasible but not recommended,
549
- because component's key and parameter's name looks like the same level.
556
+ because component's key and parameter's name seem easy to confuse.
550
557
  The recommended writing is:
551
558
 
552
559
  ```ruby
553
560
  query! :UidQuery => [:uid, String]
554
561
  ```
555
562
 
563
+ (2) You can use `schema` to define a Schema Component.
564
+
556
565
  ```ruby
557
566
  # method signature
558
- schema(component_key, type, schema_hash)
567
+ schema(component_key, type = nil, one_of: nil, all_of: nil, any_of: nil, not: nil, **schema_hash)
559
568
  # usage
560
569
  schema :Dog => [ String, desc: 'dogee' ] # <= schema_type is `String`
561
570
  # advance usage
@@ -569,9 +578,13 @@
569
578
  ]
570
579
  # or (unrecommended)
571
580
  schema :Dog, { id!: Integer, name: String }, dft: { id: 1, name: 'pet' }, desc: 'dogee'
581
+ #
582
+ # pass a ActiveRecord class constant as `component_key`,
583
+ # it will automatically read the db schema to generate the component.
584
+ schema User # easy! And the component_key will be :User
572
585
  ```
573
586
  [1] see: [Type](documentation/parameter.md#type-schema_type)
574
-
587
+
575
588
  ## Usage - Generate JSON Documentation File
576
589
 
577
590
  Use `OpenApi.write_docs`:
@@ -623,7 +636,8 @@
623
636
  end
624
637
  ```
625
638
 
626
- Notes: convention is the file name ends with `_doc.rb`
639
+ Notes: file name ends in `_doc.rb` by default, but you can change via `Config.doc_location`
640
+ (it should be file paths, defaults to `./app/**/*_doc.rb`).
627
641
 
628
642
  ### Trick2 - Global DRYing
629
643
 
@@ -669,7 +683,7 @@
669
683
 
670
684
  Pass `skip: []` and `use: []` to `api` like following code:
671
685
  ```ruby
672
- api :index, 'desc', builder: :index, skip: [ :Token ]
686
+ api :index, 'desc', skip: [ :Token ]
673
687
  ```
674
688
 
675
689
  Look at this [file](documentation/examples/goods_doc.rb) to learn more.
@@ -680,7 +694,7 @@
680
694
 
681
695
  See this [file](documentation/examples/auto_gen_doc.rb#L51) for uasge information.
682
696
 
683
- ### Trick6 - Combined Schema (oneOf / allOf / anyOf / not)
697
+ ### Trick6 - Combined Schema (one_of / all_of / any_of / not)
684
698
 
685
699
  ```ruby
686
700
  query :combination, one_of: [ :GoodSchema, String, { type: Integer, desc: 'integer input'}]
@@ -709,7 +723,7 @@
709
723
  - **Report error when require `routes.rb`?***
710
724
  1. Run `rails routes`.
711
725
  2. Copy the output to a file, for example `config/routes.txt`.
712
- ignore the file `config/routes.txt`.
726
+ Ignore the file `config/routes.txt`.
713
727
  3. Put `c.rails_routes_file = 'config/routes.txt'` to your ZRO config.
714
728
 
715
729
 
data/README_zh.md CHANGED
@@ -1 +1,747 @@
1
- TODO = =
1
+ # ZRO: Rails 应用 OpenApi3 JSON 文档生成器
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/zero-rails_openapi.svg)](https://badge.fury.io/rb/zero-rails_openapi)
4
+ [![Build Status](https://travis-ci.org/zhandao/zero-rails_openapi.svg?branch=master)](https://travis-ci.org/zhandao/zero-rails_openapi)
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/471fd60f6eb7b019ceed/maintainability)](https://codeclimate.com/github/zhandao/zero-rails_openapi/maintainability)
6
+
7
+ 一套简洁的 DSL,用于为 Rails 应用生成 OpenAPI Specification 3 (**OAS3**, 旧称「Swagger3」) 标准的 JSON 文档。
8
+ (你还可以使用 Swagger-UI 3.2.0 以上版本来可视化所生成的文档。)
9
+
10
+ ## Contributing
11
+
12
+ **这里是栈刀 = ▽ =
13
+ 如果你在寻找能清晰书写 OAS API 文档的 DSL 工具,俺这个还挺不错的 ~
14
+ 你还可以复用其所[产出](#about-openapidocs-and-openapipaths_index)来写一些扩展,比如参数自动校验什么的(我有写哦)。
15
+ 有什么想法敬请 PR,谢过!
16
+ 另外,走过路过不妨来个 star?**
17
+
18
+ ## Table of Contents
19
+
20
+ - [关于 OAS](#about-oas) (OpenAPI Specification)
21
+ - [安装](#installation)
22
+ - [配置](#configure)
23
+ - [DSL 介绍及用例](#usage---dsl)
24
+ - [用于 `api` 和 `api_dry` 块内的 DSL(描述 API 的参数、响应等)](#dsl-methods-inside-api-and-api_drys-block)
25
+ - [用于 `components` 块内的 DSL(描述可复用的组件)](#dsl-methods-inside-componentss-block-code-source)
26
+ - [执行文档生成](#usage---generate-json-documentation-file)
27
+ - [使用 Swagger-UI 可视化所生成的文档](#usage---use-swagger-uivery-beautiful-web-page-to-show-your-documentation)
28
+ - [技巧](#tricks)
29
+ - [将 DSL 写于他处,与控制器分离](#trick1---write-the-dsl-somewhere-else)
30
+ - [全局 DRY](#trick2---global-drying)
31
+ - [基于 enum 等信息自动生成参数描述](#trick3---auto-generate-description)
32
+ - [跳过或使用 DRY 时(`api_dry`)所定义的参数](#trick4---skip-or-use-parameters-define-in-api_dry)
33
+ - [基于 DB Schema 自动生成 response 的格式](#trick5---auto-generate-indexshow-actionss-response-types-based-on-db-schema)
34
+ - [定义组合的 Schema (one_of / all_of / any_of / not)](#trick6---combined-schema-one_of--all_of--any_of--not)
35
+ - [问题集](#troubleshooting)
36
+ - [有关 `OpenApi.docs` 和 `OpenApi.paths_index`](#about-openapidocs-and-openapipaths_index)
37
+
38
+ ## About OAS
39
+
40
+ 有关 OAS3 的所有内容请看 [OpenAPI Specification](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md)
41
+
42
+ 你也可以看这份文档做初步的了解 [swagger.io](https://swagger.io/docs/specification/basic-structure/)
43
+
44
+ **我建议你应该至少了解 OAS3 的基本结构**
45
+ 比如说 component(组件)—— 这能帮助你进一步减少书写文档 DSL 的代码(如果其中有很多可复用的数据结构的话)。
46
+
47
+ ## Installation
48
+
49
+ 选一行添加到 Gemfile:
50
+
51
+ ```ruby
52
+ gem 'zero-rails_openapi'
53
+ # or
54
+ gem 'zero-rails_openapi', github: 'zhandao/zero-rails_openapi'
55
+ ```
56
+
57
+ 命令行执行:
58
+
59
+ $ bundle
60
+
61
+ ## Configure
62
+
63
+ 新建一个 initializer, 用来配置 ZRO 并定义你的文档。
64
+
65
+ 这是一个简单的示例:
66
+
67
+ ```ruby
68
+ # config/initializers/open_api.rb
69
+ require 'open_api'
70
+
71
+ OpenApi::Config.tap do |c|
72
+ # [REQUIRED] The output location where .json doc file will be written to.
73
+ c.file_output_path = 'public/open_api'
74
+
75
+ c.open_api_docs = {
76
+ # 对文档 `homepage` 进行定义
77
+ homepage: {
78
+ # [REQUIRED] ZRO will scan all the descendants of root_controller, then generate their docs.
79
+ root_controller: Api::V1::BaseController,
80
+
81
+ # [REQUIRED] OAS Info Object: The section contains API information.
82
+ info: {
83
+ # [REQUIRED] The title of the application.
84
+ title: 'Homepage APIs',
85
+ # Description of the application.
86
+ description: 'API documentation of Rails Application. <br/>' \
87
+ 'Optional multiline or single-line Markdown-formatted description ' \
88
+ 'in [CommonMark](http://spec.commonmark.org/) or `HTML`.',
89
+ # [REQUIRED] The version of the OpenAPI document
90
+ # (which is distinct from the OAS version or the API implementation version).
91
+ version: '1.0.0'
92
+ }
93
+ }
94
+ }
95
+ end
96
+ ```
97
+
98
+ 除了直接使用 Hash,你还可以使用 DSL 来定义文档的基本信息:
99
+
100
+ ```ruby
101
+ # config/initializers/open_api.rb
102
+ require 'open_api'
103
+
104
+ OpenApi::Config.tap do |c|
105
+ c.instance_eval do
106
+ open_api :homepage_api, root_controller: ApiDoc
107
+ info version: '1.0.0', title: 'Homepage APIs'
108
+ end
109
+ end
110
+ ```
111
+
112
+ 更多更详尽的配置和文档信息定义示例: [open_api.rb](documentation/examples/open_api.rb)
113
+ 所有你可以配置的项目: [config.rb](lib/open_api/config.rb)
114
+ 所有你可以使用的文档信息 DSL: [config_dsl.rb](lib/open_api/config_dsl.rb)
115
+
116
+ ## Usage - DSL
117
+
118
+ ### 首先,`include OpenApi::DSL` 到你用来写文档的基类中,例如:
119
+
120
+ ```ruby
121
+ # app/controllers/api/api_controller.rb
122
+ class ApiController < ActionController::API
123
+ include OpenApi::DSL
124
+ end
125
+ ```
126
+
127
+ ### DSL 使用实例
128
+
129
+ 这是一个最简单的实例:
130
+
131
+ ```ruby
132
+ class Api::V1::ExamplesController < Api::V1::BaseController
133
+ api :index, 'GET list' do
134
+ query :page, Integer#, desc: 'page, greater than 1', range: { ge: 1 }, dft: 1
135
+ query :rows, Integer#, desc: 'per page', range: { ge: 1 }, default: 10
136
+ end
137
+ end
138
+ ```
139
+
140
+ 可以查看两份更详细的实例: [goods_doc.rb](documentation/examples/goods_doc.rb), 以及
141
+ [examples_controller.rb](documentation/examples/examples_controller.rb)
142
+
143
+ ### 作为类方法的 DSL ([source code](lib/open_api/dsl.rb))
144
+
145
+ #### (1) `ctrl_path` (controller path) [无需调用,当且仅当你是在控制器中写文档时]
146
+
147
+ ```ruby
148
+ # method signature
149
+ ctrl_path(path)
150
+ # usage
151
+ ctrl_path 'api/v1/examples'
152
+ ```
153
+ 其默认设定为 `controller_path`.
154
+
155
+ [这个技巧](#trick1---write-the-dsl-somewhere-else) 展示如何使用 `ctrl_path` 来让你将 DSL 写在他处(与控制器分离),来简化你的控制器。
156
+
157
+ #### (2) `apis_tag` [optional]
158
+
159
+ ```ruby
160
+ # method signature
161
+ apis_tag(name: nil, desc: '', external_doc_url: '')
162
+ # usage
163
+ apis_tag name: 'ExampleTagName', desc: 'ExamplesController\'s APIs'
164
+ ```
165
+ 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)).
166
+
167
+ desc and external_doc_url will be output to the tags[the current tag] (tag defaults to controller_name), but are optional.
168
+
169
+ #### (3) `components` [optional]
170
+
171
+ ```ruby
172
+ # method signature
173
+ components(&block)
174
+ # usage
175
+ components do
176
+ # DSL for defining components
177
+ schema :DogSchema => [ { id: Integer, name: String }, dft: { id: 1, name: 'pet' } ]
178
+ query! :UidQuery => [ :uid, String, desc: 'uid' ]
179
+ resp :BadRqResp => [ 'bad request', :json ]
180
+ end
181
+
182
+ # to use component
183
+ api :action, 'summary' do
184
+ query :doge, :DogSchema # to use a Schema component
185
+ param_ref :UidQuery # to use a Parameter component
186
+ response_ref :BadRqResp # to use a Response component
187
+ end
188
+ ```
189
+ Component can be used to simplify your DSL code (by using `*_ref` methods).
190
+
191
+ Each RefObj you defined is associated with components through component key.
192
+ We suggest that component keys should be camelized symbol.
193
+
194
+ #### (4) `api_dry` [optional]
195
+
196
+ This method is for DRYing.
197
+
198
+ ```ruby
199
+ # method signature
200
+ api_dry(action = :all, desc = '', &block)
201
+ # usage
202
+ api_dry :all, 'common response' # block ...
203
+ api_dry :index # block ...
204
+ api_dry [:index, :show] do
205
+ query! #...
206
+ end
207
+ ```
208
+
209
+ As you think, the block will be executed to each specified API(action) **firstly**.
210
+
211
+ #### (5) `api` [required]
212
+
213
+ Define the specified API (controller action, in the following example is index).
214
+
215
+ ```ruby
216
+ # method signature
217
+ api(action, summary = '', builder: nil, skip: [ ], use: [ ], &block)
218
+ # usage
219
+ api :index, '(SUMMARY) this api blah blah ...', builder: :index # block ...
220
+ ```
221
+ If you pass `builder`, and `generate_jbuilder_file` is set to `true` (in your initializer),
222
+ ZRO will generate JBuilder file by using specified template called `index`.
223
+ About template settings, see: [open_api.rb](documentation/examples/open_api.rb)
224
+
225
+ `use` and `skip` options: to use or skip the parameters defined in `api_dry`.
226
+
227
+ ```ruby
228
+ api :show, 'summary', use: [:id] # => it will only take :id from DRYed result.
229
+ ```
230
+
231
+ ### DSL methods inside [api]() and [api_dry]()'s block
232
+
233
+ [source code](lib/open_api/dsl/api_info_obj.rb)
234
+
235
+ These following methods in the block describe the specified API action: description, valid?,
236
+ parameters, request body, responses, securities, servers.
237
+
238
+ (Here corresponds to OAS [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#operationObject))
239
+
240
+ #### (1) `this_api_is_invalid!`, its aliases:
241
+ ```
242
+ this_api_is_expired!
243
+ this_api_is_unused!
244
+ this_api_is_under_repair!
245
+ ```
246
+
247
+ ```ruby
248
+ # method signature
249
+ this_api_is_invalid!(explain = '')
250
+ # usage
251
+ this_api_is_invalid! 'this api is expired!'
252
+ ```
253
+
254
+ Then `deprecated` of this API will be set to true.
255
+
256
+ #### (2) `desc`: description for the current API and its inputs (parameters and request body)
257
+
258
+ ```ruby
259
+ # method signature
260
+ desc(desc, param_descs = { })
261
+ # usage
262
+ desc 'current API\'s description',
263
+ id: 'desc of the parameter :id',
264
+ email: 'desc of the parameter :email'
265
+ ```
266
+
267
+ 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)),
268
+ but that will make it long and ugly. We recommend that unite descriptions in this place.
269
+
270
+ In addition, when you want to dry the same parameters (each with a different description), it will be of great use.
271
+
272
+ #### (3) `param` family methods (OAS - [Parameter Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#parameterObject))
273
+
274
+ Define the parameters for the API (action).
275
+ ```
276
+ param
277
+ param_ref # for reuse component,
278
+ # it links sepcified RefObjs (by component keys) to current parameters.
279
+ header, path, query, cookie # will pass specified parameter location to `param`
280
+ header!, path!, query!, cookie! # bang method of above methods
281
+ do_* by: { parameter_definations } # batch definition parameters, such as do_path, do_query
282
+ order # order parameters by names array you passed
283
+ examples # define examples of parameters
284
+ ```
285
+ **The bang method (which's name is end of a exclamation point `!`) means this param is required, so without `!` means optional.**
286
+ **THE SAME BELOW.**
287
+
288
+ ```ruby
289
+ # `param_type` just is the location of parameter, like: query, path
290
+ # `schema_type` is the type of parameter, like: String, Integer (must be a constant)
291
+ # For more explanation, please click the link below ↓↓↓
292
+ # method signature
293
+ param(param_type, param_name, schema_type, is_required, schema_hash = { })
294
+ # usage
295
+ param :query, :page, Integer, :req, range: { gt: 0, le: 5 }, desc: 'page'
296
+
297
+
298
+ # method signature
299
+ param_ref(component_key, *component_keys) # should pass at least 1 key
300
+ # usage
301
+ param_ref :IdPath
302
+ param_ref :IdPath, :NameQuery, :TokenHeader
303
+
304
+
305
+ ### method signature
306
+ header(param_name, schema_type = nil, one_of: nil, all_of: nil, any_of: nil, not: nil, **schema_hash)
307
+ header!(param_name, schema_type = nil, one_of: nil, all_of: nil, any_of: nil, not: nil, **schema_hash)
308
+ query!(param_name, schema_type = nil, one_of: nil, all_of: nil, any_of: nil, not: nil, **schema_hash)
309
+ # ...
310
+ ### usage
311
+ header! 'Token', String
312
+ query! :readed, Boolean, must_be: true, default: false
313
+ # The same effect as above, but not simple
314
+ param :query, :readed, Boolean, :req, must_be: true, default: false
315
+ #
316
+ # When schema_type is a Object
317
+ # (describe by hash, key means prop's name, value means prop's schema_type)
318
+ query :good, { name: String, price: Float, spec: { size: String, weight: Integer } }, desc: 'good info'
319
+ # Or you can use `type:` to sign the schema_type, maybe this is clearer for describing object
320
+ query :good, type: { name: String, price: Float, spec: { size: String, weight: Integer } }, desc: 'good info'
321
+ #
322
+ query :good_name, type: String # It's also OK, but some superfluous
323
+ query :good_name, String # recommended
324
+ # About Combined Schema (`one_of` ..), see the link below.
325
+
326
+
327
+ # method signature
328
+ do_query(by:)
329
+ # usage
330
+ do_query by: {
331
+ search_type: String,
332
+ search_val: String,
333
+ export!: Boolean
334
+ }
335
+ # The same effect as above, but a little bit repetitive
336
+ query :search_type, String
337
+ query :search_val, String
338
+ query! :export, Boolean
339
+
340
+
341
+ # method signature
342
+ # `exp_by` (select_example_by): choose the example fields.
343
+ examples(exp_by = :all, examples_hash)
344
+ # usage
345
+ # it defines 2 examples by using parameter :id and :name
346
+ # if pass :all to `exp_by`, keys will be all the parameter's names.
347
+ examples [:id, :name], {
348
+ :right_input => [ 1, 'user'], # == { id: 1, name: 'user' }
349
+ :wrong_input => [ -1, '' ]
350
+ }
351
+ ```
352
+
353
+ [This trick show you how to define combined schema (by using `one_of` ..)](#trick6---combined-schema-one-of--all-of--any-of--not)
354
+
355
+ [**>> More About `param` DSL <<**](documentation/parameter.md)
356
+
357
+ #### (4) `request_body` family methods (OAS - [Request Body Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#requestBodyObject))
358
+
359
+ OpenAPI 3.0 uses the requestBody keyword to distinguish the payload from parameters.
360
+ ```
361
+ request_body
362
+ body_ref # for reuse component,
363
+ # it links sepcified RefObjs (by component keys) to current body.
364
+ body, body! # alias of request_body
365
+ form, form! # define a multipart/form-data body
366
+ file, file! # define a File media-type body
367
+ ```
368
+
369
+ ```ruby
370
+ # method signature
371
+ request_body(is_required, media_type, desc = '', schema_hash = { })
372
+ # usage
373
+ request_body :opt, :form, '', type: { id!: Integer, name: String }
374
+ # or
375
+ request_body :opt, :form, '', data: { id!: Integer, name: String }
376
+
377
+
378
+ # method signature
379
+ body_ref(component_key)
380
+ # usage
381
+ body_ref :UpdateDogeBody
382
+
383
+
384
+ # method signature
385
+ body!(media_type, desc = '', schema_hash = { })
386
+ # usage
387
+ body :json
388
+
389
+
390
+ # method implement
391
+ def form desc = '', schema_hash = { }
392
+ body :form, desc, schema_hash
393
+ end
394
+ # usage
395
+ form! 'register', data: {
396
+ name: String,
397
+ password: String,
398
+ password_confirmation: String
399
+ }
400
+ # advance usage
401
+ form 'for creating a user', data: {
402
+ :name! => { type: String, desc: 'user name' },
403
+ :password! => { type: String, pattern: /[0-9]{6,10}/, desc: 'password' },
404
+ # optional
405
+ :remarks => { type: String, desc: 'remarks' },
406
+ }, exp_by: %i[ name password ],
407
+ examples: { # ↓ ↓
408
+ :right_input => [ 'user1', '123456' ],
409
+ :wrong_input => [ 'user2', 'abc' ]
410
+ }
411
+
412
+
413
+ # about `file`
414
+ def file! media_type, desc = '', schema_hash = { type: File }
415
+ body! media_type, desc, schema_hash
416
+ end
417
+ ```
418
+
419
+ 1. **Notice:** Each API should only declare a request body
420
+ That is, all of the above methods you can only choose one of them.
421
+ (But **multiple media types** will be supported in the future).
422
+ 2. `media_type`: we provide some [mapping](lib/oas_objs/media_type_obj.rb) from symbols to real media-types.
423
+ 3. `schema_hash`: as above (see param).
424
+ **One thing that should be noted is: when use Hash writing, `scham_type` is writed in schema_hash using key :type.**
425
+ 4. `exp_by` and `examples`: for the above example, the following has the same effect:
426
+ ```
427
+ examples: {
428
+ :right_input => { name: 'user1', password: '123456' },
429
+ :wrong_input => { name: 'user2', password: 'abc' }
430
+ }
431
+ ```
432
+
433
+ #### (5) `response` family methods (OAS - [Response Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#response-object))
434
+
435
+ Define the responses for the API (action).
436
+ ```
437
+ response or resp
438
+ response_ref
439
+ default_response or dft_resp
440
+ error_response, other_response, oth_resp, error, err_resp # response's aliases, should be used in the error response context.
441
+ merge_to_resp
442
+ ```
443
+
444
+ ```ruby
445
+ # method signature
446
+ response(response_code, desc, media_type = nil, schema_hash = { })
447
+ # usage
448
+ response 200, 'query result', :pdf, type: File
449
+
450
+ # method signature
451
+ response_ref(code_compkey_hash)
452
+ # usage
453
+ response_ref 700 => :AResp, 800 => :BResp
454
+
455
+ # method signature
456
+ merge_to_resp(code, by:)
457
+ # usage
458
+ merge_to_resp 200, by: {
459
+ data: {
460
+ type: String
461
+ }
462
+ }
463
+ ```
464
+
465
+ **practice:** Combined with wrong class, automatically generate error responses. [AutoGenDoc](documentation/examples/auto_gen_doc.rb#L63)
466
+
467
+ #### (6) Authentication and Authorization
468
+
469
+ First of all, please make sure that you have read one of the following documents:
470
+ [OpenApi Auth](https://swagger.io/docs/specification/authentication/)
471
+ or [securitySchemeObject](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securitySchemeObject)
472
+
473
+ ##### Define Security Scheme
474
+
475
+ Use these DSL in your initializer or `components` block:
476
+ ```
477
+ security_scheme # alias `auth_scheme`
478
+ base_auth # will call `security_scheme`
479
+ bearer_auth # will call `security_scheme`
480
+ api_key # will call `security_scheme`
481
+ ```
482
+ It's very simple to use (if you understand the above document)
483
+ ```ruby
484
+ # method signature
485
+ security_scheme(scheme_name, other_info)
486
+ # usage
487
+ security_scheme :BasicAuth, { type: 'http', scheme: 'basic', desc: 'basic auth' }
488
+
489
+ # method signature
490
+ base_auth(scheme_name, other_info = { })
491
+ bearer_auth(scheme_name, format = 'JWT', other_info = { })
492
+ api_key(scheme_name, field:, in:, **other_info)
493
+ # usage
494
+ base_auth :BasicAuth, desc: 'basic auth' # the same effect as ↑↑↑
495
+ bearer_auth :Token
496
+ api_key :ApiKeyAuth, field: 'X-API-Key', in: 'header', desc: 'pass api key to header'
497
+ ```
498
+
499
+ ##### Apply Security
500
+
501
+ ```
502
+ # In initializer
503
+ # Global effectiveness
504
+ global_security_require
505
+ global_security # alias
506
+ global_auth # alias
507
+
508
+ # In `api`'s block
509
+ # Only valid for the current controller
510
+ security_require
511
+ security # alias
512
+ auth # alias
513
+ need_auth # alias
514
+ ```
515
+ Name is different, signature and usage is similar.
516
+ ```ruby
517
+ # method signature
518
+ security_require(scheme_name, scopes: [ ])
519
+ # usage
520
+ global_auth :Token
521
+ need_auth :Token
522
+ auth :OAuth, scopes: %w[ read_example admin ]
523
+ ```
524
+
525
+ #### (7) Overriding Global Servers by `server`
526
+
527
+ ```ruby
528
+ # method signature
529
+ server(url, desc)
530
+ # usage
531
+ server 'http://localhost:3000', 'local'
532
+ ```
533
+
534
+ ### DSL methods inside [components]()'s block ([code source](lib/open_api/dsl/components.rb))
535
+
536
+ (Here corresponds to OAS [Components Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#componentsObject))
537
+
538
+ Inside `components`'s block,
539
+ you can use the same DSL as [[DSL methods inside `api` and `api_dry`'s block]](#dsl-methods-inside-api-and-api_drys-block).
540
+ But there are two differences:
541
+
542
+ (1) Each method needs to pass one more parameter `component_key`
543
+ (in the first parameter position),
544
+ this will be used as the reference name for the component.
545
+
546
+ ```ruby
547
+ query! :UidQuery, :uid, String
548
+ ```
549
+ This writing is feasible but not recommended,
550
+ because component's key and parameter's name seem easy to confuse.
551
+ The recommended writing is:
552
+
553
+ ```ruby
554
+ query! :UidQuery => [:uid, String]
555
+ ```
556
+
557
+ (2) You can use `schema` to define a Schema Component.
558
+
559
+ ```ruby
560
+ # method signature
561
+ schema(component_key, type = nil, one_of: nil, all_of: nil, any_of: nil, not: nil, **schema_hash)
562
+ # usage
563
+ schema :Dog => [ String, desc: 'dogee' ] # <= schema_type is `String`
564
+ # advance usage
565
+ schema :Dog => [
566
+ {
567
+ id!: Integer,
568
+ name: { type: String, must_be: 'name', desc: 'name' }
569
+ }, # <= this hash is schema type[1]
570
+ dft: { id: 1, name: 'pet' },
571
+ desc: 'dogee'
572
+ ]
573
+ # or (unrecommended)
574
+ schema :Dog, { id!: Integer, name: String }, dft: { id: 1, name: 'pet' }, desc: 'dogee'
575
+ #
576
+ # pass a ActiveRecord class constant as `component_key`,
577
+ # it will automatically read the db schema to generate the component.
578
+ schema User # easy! And the component_key will be :User
579
+ ```
580
+ [1] see: [Type](documentation/parameter.md#type-schema_type)
581
+
582
+ ## Usage - Generate JSON Documentation File
583
+
584
+ Use `OpenApi.write_docs`:
585
+
586
+ ```ruby
587
+ # initializer
588
+ OpenApi.write_docs generate_files: !Rails.env.production?
589
+
590
+ # or run directly in console
591
+ OpenApi.write_docs # will generate json doc files
592
+ ```
593
+
594
+ Then the JSON files will be written to the directories you set. (Each API a file.)
595
+
596
+ ## Usage - Use Swagger UI(very beautiful web page) to show your Documentation
597
+
598
+ Download [Swagger UI](https://github.com/swagger-api/swagger-ui) (version >= 2.3.0 support the OAS3)
599
+ to your project,
600
+ change the default JSON file path(url) in index.html.
601
+ In order to use it, you may have to enable CORS, [see](https://github.com/swagger-api/swagger-ui#cors-support)
602
+
603
+ ## Tricks
604
+
605
+ ### Trick1 - Write the DSL Somewhere Else
606
+
607
+ Does your documentation take too many lines?
608
+ Do you want to separate documentation from business controller to simplify both?
609
+ Very easy! Just follow
610
+
611
+ ```ruby
612
+ # config/initializers/open_api.rb
613
+ # in your configuration
614
+ root_controller: ApiDoc
615
+
616
+ # app/api_doc/api_doc.rb
617
+ require 'open_api/dsl'
618
+
619
+ class ApiDoc < Object
620
+ include OpenApi::DSL
621
+ end
622
+
623
+ # app/api_doc/v1/examples_doc.rb
624
+ class V1::ExamplesDoc < ApiDoc
625
+ ctrl_path 'api/v1/examples'
626
+
627
+ api :index do
628
+ # ...
629
+ end
630
+ end
631
+ ```
632
+
633
+ Notes: file name ends in `_doc.rb` by default, but you can change via `Config.doc_location`
634
+ (it should be file paths, defaults to `./app/**/*_doc.rb`).
635
+
636
+ ### Trick2 - Global DRYing
637
+
638
+ Method `api_dry` is for DRY but its scope is limited to the current controller.
639
+
640
+ I have no idea of best practices, But you can look at this [file](documentation/examples/auto_gen_doc.rb).
641
+ The implementation of the file is: do `api_dry` when inherits the base controller inside `inherited` method.
642
+
643
+ You can use `sort` to specify the order of parameters.
644
+
645
+ ### Trick3 - Auto Generate Description
646
+
647
+ ```ruby
648
+ desc 'api desc',
649
+ search_type!: 'search field, allows:<br/>'
650
+ query :search_type, String, enum: %w[name creator category price]
651
+
652
+ # or
653
+
654
+ query :search_type, String, desc!: 'search field, allows:<br/>',
655
+ enum: %w[name creator category price]
656
+ ```
657
+
658
+ Notice `!` use (`search_type!`, `desc!`), it tells ZRO to append
659
+ information that analyzed from definitions (enum, must_be ..) to description automatically.
660
+
661
+ Any one of above will generate:
662
+ > search field, allows:<br/>1/ name<br/>2/ creator,<br/>3/ category<br/>4/ price<br/>
663
+
664
+ You can also use Hash to define `enum`:
665
+ ```ruby
666
+ query :view, String, desc: 'allows values<br/>', enum: {
667
+ 'all goods (default)': :all,
668
+ 'only online': :online,
669
+ 'only offline': :offline,
670
+ 'expensive goods': :get,
671
+ 'cheap goods': :borrow,
672
+ }
673
+ ```
674
+ Read this [file](documentation/examples/auto_gen_desc.rb) to learn more.
675
+
676
+ ### Trick4 - Skip or Use parameters define in api_dry
677
+
678
+ Pass `skip: []` and `use: []` to `api` like following code:
679
+ ```ruby
680
+ api :index, 'desc', builder: :index, skip: [ :Token ]
681
+ ```
682
+
683
+ Look at this [file](documentation/examples/goods_doc.rb) to learn more.
684
+
685
+ ### Trick5 - Auto Generate index/show Actions's Response-Types Based on DB Schema
686
+
687
+ Use method `load_schema` in `api_dry`.
688
+
689
+ See this [file](documentation/examples/auto_gen_doc.rb#L51) for uasge information.
690
+
691
+ ### Trick6 - Combined Schema (one_of / all_of / any_of / not)
692
+
693
+ ```ruby
694
+ query :combination, one_of: [ :GoodSchema, String, { type: Integer, desc: 'integer input'}]
695
+
696
+ form '', data: {
697
+ :combination_in_form => { any_of: [ Integer, String ] }
698
+ }
699
+
700
+ schema :PetSchema => [ not: [ Integer, Boolean ] ]
701
+ ```
702
+
703
+ OAS: [link1](https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/),
704
+ [link2](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject)
705
+
706
+ ## Troubleshooting
707
+
708
+ - **You wrote document of the current API, but not find in the generated json file?**
709
+ Check your routing settings.
710
+ - **Undefine method `match?`**
711
+ Monkey patches for `String` and `Symbol`:
712
+ ```ruby
713
+ class String # Symbol
714
+ def match?(pattern); !match(pattern).nil? end
715
+ end
716
+ ```
717
+ - **Report error when require `routes.rb`?***
718
+ 1. Run `rails routes`.
719
+ 2. Copy the output to a file, for example `config/routes.txt`.
720
+ Ignore the file `config/routes.txt`.
721
+ 3. Put `c.rails_routes_file = 'config/routes.txt'` to your ZRO config.
722
+
723
+
724
+ ## About `OpenApi.docs` and `OpenApi.paths_index`
725
+
726
+ After `OpenApi.write_docs`, the above two module variables will be generated.
727
+
728
+ `OpenApi.docs`: A Hash with API names as keys, and documents of each APIs as values.
729
+ documents are instances of ActiveSupport::HashWithIndifferentAccess.
730
+
731
+ `OpenApi.paths_index`: Inverted index of controller path to API name mappings.
732
+ Like: `{ 'api/v1/examples' => :homepage_api }`
733
+ It's useful when you want to look up a document based on a controller and do something.
734
+
735
+ ## Development
736
+
737
+ 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.
738
+
739
+ 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).
740
+
741
+ ## License
742
+
743
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
744
+
745
+ ## Code of Conduct
746
+
747
+ 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).