zero-rails_openapi 1.4.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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).