oas_rails 0.7.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -9
- data/app/controllers/oas_rails/oas_rails_controller.rb +3 -2
- data/app/views/layouts/oas_rails/application.html.erb +13 -0
- data/app/views/oas_rails/oas_rails/index.html.erb +15 -27
- data/lib/generators/oas_rails/config/templates/oas_rails_initializer.rb +9 -0
- data/lib/oas_rails/configuration.rb +4 -0
- data/lib/oas_rails/extractors/route_extractor.rb +22 -0
- data/lib/oas_rails/version.rb +1 -1
- data/lib/oas_rails/yard/oas_rails_factory.rb +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05b39d8ca4348b3da83595a029b436a73ba17a7a6da61ff61b09c02dd6147e7f
|
4
|
+
data.tar.gz: e8ef2175c8824dc45c63ef2aa112a1339ff5c4db779635ea4067d7bfd6dd75b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1cce603fbc0064bc84a3a953026aae6eb914b33872b20ebb1620195a4e4105736965c3816e664a708b4367adacce57d7003fb23646908f0ad5337f6a34fa5ee
|
7
|
+
data.tar.gz: 070ec97c6bb4e46cfcd1f6f5b1d5a71fda212dd8d197c74623900ff057d614f2a387aa79c67eb7fd832bd7b36ae2fefd105b8159991263fd219b7a9718691e7a
|
data/README.md
CHANGED
@@ -5,10 +5,14 @@
|
|
5
5
|
![Static Badge](https://img.shields.io/badge/Rails-%3E%3D7.0.0-%23E9573F)
|
6
6
|
![Static Badge](https://img.shields.io/badge/Ruby-%3E%3D3.1.0-%23E9573F)
|
7
7
|
|
8
|
-
# Open API Specification For Rails
|
8
|
+
# 📃Open API Specification For Rails
|
9
9
|
|
10
10
|
OasRails is a Rails engine for generating **automatic interactive documentation for your Rails APIs**. It generates an **OAS 3.1** document and displays it using **[RapiDoc](https://rapidocweb.com)**.
|
11
11
|
|
12
|
+
🎬 A Demo Video Here:
|
13
|
+
https://vimeo.com/1013687332
|
14
|
+
🎬
|
15
|
+
|
12
16
|
![Screenshot](https://a-chacon.com/assets/images/oas_rails_ui.png)
|
13
17
|
|
14
18
|
## Related Projects
|
@@ -25,7 +29,7 @@ OasRails is a Rails engine for generating **automatic interactive documentation
|
|
25
29
|
- **Simple**: Complement default documentation with a few comments; no need to learn a complex DSL
|
26
30
|
- **Pure Ruby on Rails APIs**: No additional frameworks needed (e.g., Grape, RSpec)
|
27
31
|
|
28
|
-
## Motivation
|
32
|
+
## 📽️ Motivation
|
29
33
|
|
30
34
|
After experiencing the interactive documentation in Python's fast-api framework, I sought similar functionality in Ruby on Rails. Unable to find a suitable solution, I [asked on Stack Overflow](https://stackoverflow.com/questions/71947018/is-there-a-way-to-generate-an-interactive-documentation-for-rails-apis) years ago. Now, with some free time while freelancing as an API developer, I decided to build my own tool.
|
31
35
|
|
@@ -33,7 +37,7 @@ After experiencing the interactive documentation in Python's fast-api framework,
|
|
33
37
|
|
34
38
|
The goal is to minimize the effort required to create comprehensive documentation. By following REST principles in Rails, we believe this is achievable. You can enhance the documentation using [Yard](https://yardoc.org/) tags.
|
35
39
|
|
36
|
-
## Table of Contents
|
40
|
+
## 📋 Table of Contents
|
37
41
|
|
38
42
|
- [Installation](#installation)
|
39
43
|
- [Configuration](#configuration)
|
@@ -74,7 +78,7 @@ The goal is to minimize the effort required to create comprehensive documentatio
|
|
74
78
|
|
75
79
|
You'll now have **basic documentation** based on your routes and automatically gathered information at `localhost:3000/docs`. To enhance it, create an initializer file and add [Yard](https://yardoc.org/) tags to your controller methods.
|
76
80
|
|
77
|
-
## Configuration
|
81
|
+
## ⚙️ Configuration
|
78
82
|
|
79
83
|
To configure OasRails, you MUST create an initializer file including all your settings. The first step is to create your initializer file, which you can easily do with:
|
80
84
|
|
@@ -107,6 +111,7 @@ Then fill it with your data. Below are the available configuration options:
|
|
107
111
|
- `config.autodiscover_request_body`: Automatically detects request bodies for create/update methods. Default is `true`.
|
108
112
|
- `config.autodiscover_responses`: Automatically detects responses from controller renders. Default is `true`.
|
109
113
|
- `config.api_path`: Sets the API path if your API is under a different namespace.
|
114
|
+
- `config.ignored_actions`: Sets an array with the controller or controller#action. No necessary to add api_path before.
|
110
115
|
|
111
116
|
### Authentication Settings
|
112
117
|
|
@@ -122,7 +127,7 @@ Then fill it with your data. Below are the available configuration options:
|
|
122
127
|
|
123
128
|
- `config.response_body_of_default`: body for use in default responses. It must be a String hash like the used in request body tags. Default: "{ message: String }"
|
124
129
|
|
125
|
-
## Usage
|
130
|
+
## 📓 Usage
|
126
131
|
|
127
132
|
In addition to the information provided in the initializer file and the data that can be extracted from the routes and methods automatically, it is essential to document your API in the following way. The documentation is created **with the help of YARD**, so the methods are documented with **comment tags**.
|
128
133
|
|
@@ -147,11 +152,11 @@ Used to add a summary to the endpoint. It replaces the default summary/title of
|
|
147
152
|
|
148
153
|
**Structure**: `@parameter name(position) [type] text`
|
149
154
|
|
150
|
-
Represents a parameter for the endpoint. The position can be: `header`, `path`, `cookie`, or `query`. The type should be a valid Ruby class: `String`, `Integer`, `Array<String>`, etc. Add a `!`
|
155
|
+
Represents a parameter for the endpoint. The position can be: `header`, `path`, `cookie`, or `query`. The type should be a valid Ruby class: `String`, `Integer`, `Array<String>`, etc. Add a `!` before the class to indicate a required parameter.
|
151
156
|
|
152
157
|
**Examples**:
|
153
158
|
`# @parameter page(query) [Integer] The page number.`
|
154
|
-
`# @parameter slug(path) [String
|
159
|
+
`# @parameter slug(path) [!String] Slug of the Project.`
|
155
160
|
|
156
161
|
</details>
|
157
162
|
|
@@ -333,7 +338,7 @@ class UsersController < ApplicationController
|
|
333
338
|
end
|
334
339
|
```
|
335
340
|
|
336
|
-
## Securing the OasRails Engine
|
341
|
+
## 🔒Securing the OasRails Engine
|
337
342
|
|
338
343
|
To secure the OasRails engine, which exposes an endpoint for showing the OAS definition, you can configure authentication to ensure that only authorized users have access. Here are a few methods to achieve this:
|
339
344
|
|
@@ -382,7 +387,7 @@ ActiveSupport.on_load(:oas_rails_application_controller) do
|
|
382
387
|
end
|
383
388
|
```
|
384
389
|
|
385
|
-
## Customizing the View
|
390
|
+
## ⛏️ Customizing the View
|
386
391
|
|
387
392
|
The OasRails engine provides an easy way to display your OpenAPI Specification (OAS) within your Rails application. By default, it includes an `index` view in the `OasRailsController` that displays [RapiDoc](https://rapidocweb.com/) through a CDN with default configurations. You can easily override this view to replace RapiDoc entirely or configure it differently.
|
388
393
|
|
@@ -1,10 +1,11 @@
|
|
1
1
|
module OasRails
|
2
2
|
class OasRailsController < ApplicationController
|
3
|
-
layout
|
3
|
+
# Include URL help if the layout is a user-customized layout.
|
4
|
+
include Rails.application.routes.url_helpers
|
4
5
|
|
5
6
|
def index
|
6
7
|
respond_to do |format|
|
7
|
-
format.html
|
8
|
+
format.html { render "index", layout: OasRails.config.layout }
|
8
9
|
format.json do
|
9
10
|
render json: OasRails.build.to_json, status: :ok
|
10
11
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title><%= OasRails.config.info.title %></title>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<%= csp_meta_tag %>
|
7
|
+
<meta charset="utf-8">
|
8
|
+
<!-- Important: rapi-doc uses utf8 characters -->
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<%= yield %>
|
12
|
+
</body>
|
13
|
+
</html>
|
@@ -1,27 +1,15 @@
|
|
1
|
-
|
2
|
-
<
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
text-color= "#f7f7f7"
|
17
|
-
show-header = 'false'
|
18
|
-
primary-color = "#2de410"
|
19
|
-
font-size="largest"
|
20
|
-
show-method-in-nav-bar="as-colored-text"
|
21
|
-
nav-text-color="#f7f7f7"
|
22
|
-
nav-item-spacing="relaxed"
|
23
|
-
allow-spec-file-download="true"
|
24
|
-
>
|
25
|
-
</rapi-doc>
|
26
|
-
</body>
|
27
|
-
</html>
|
1
|
+
<script type="module" src="https://unpkg.com/rapidoc/dist/rapidoc-min.js"></script>
|
2
|
+
<rapi-doc
|
3
|
+
spec-url = "<%= OasRails::Engine.routes.find_script_name({}) %>.json"
|
4
|
+
theme = "dark"
|
5
|
+
bg-color="#0F172A"
|
6
|
+
text-color= "#f7f7f7"
|
7
|
+
show-header = 'false'
|
8
|
+
primary-color = "#2de410"
|
9
|
+
font-size="largest"
|
10
|
+
show-method-in-nav-bar="as-colored-text"
|
11
|
+
nav-text-color="#f7f7f7"
|
12
|
+
nav-item-spacing="relaxed"
|
13
|
+
allow-spec-file-download="true"
|
14
|
+
>
|
15
|
+
</rapi-doc>
|
@@ -63,6 +63,15 @@ OasRails.configure do |config|
|
|
63
63
|
# API path configuration if your API is under a different namespace
|
64
64
|
# config.api_path = "/"
|
65
65
|
|
66
|
+
# Apply your custom layout. Should be the name of your layout file
|
67
|
+
# Example: "application" if file named application.html.erb
|
68
|
+
# Default: false
|
69
|
+
# config.layout = "application"
|
70
|
+
|
71
|
+
# Excluding custom controlers or controlers#action
|
72
|
+
# Example: ["projects", "users#new"]
|
73
|
+
# config.ignored_actions = []
|
74
|
+
|
66
75
|
# #######################
|
67
76
|
# Authentication Settings
|
68
77
|
# #######################
|
@@ -1,10 +1,12 @@
|
|
1
1
|
module OasRails
|
2
2
|
class Configuration
|
3
3
|
attr_accessor :info,
|
4
|
+
:layout,
|
4
5
|
:default_tags_from,
|
5
6
|
:autodiscover_request_body,
|
6
7
|
:autodiscover_responses,
|
7
8
|
:api_path,
|
9
|
+
:ignored_actions,
|
8
10
|
:security_schemas,
|
9
11
|
:authenticate_all_routes_by_default,
|
10
12
|
:set_default_responses,
|
@@ -14,6 +16,7 @@ module OasRails
|
|
14
16
|
|
15
17
|
def initialize
|
16
18
|
@info = Spec::Info.new
|
19
|
+
@layout = false
|
17
20
|
@servers = default_servers
|
18
21
|
@tags = []
|
19
22
|
@swagger_version = '3.1.0'
|
@@ -21,6 +24,7 @@ module OasRails
|
|
21
24
|
@autodiscover_request_body = true
|
22
25
|
@autodiscover_responses = true
|
23
26
|
@api_path = "/"
|
27
|
+
@ignored_actions = []
|
24
28
|
@authenticate_all_routes_by_default = true
|
25
29
|
@security_schema = nil
|
26
30
|
@security_schemas = {}
|
@@ -93,6 +93,7 @@ module OasRails
|
|
93
93
|
return false if RAILS_DEFAULT_CONTROLLERS.any? { |default| route.defaults[:controller].start_with?(default) }
|
94
94
|
return false if RAILS_DEFAULT_PATHS.any? { |path| route.path.spec.to_s.include?(path) }
|
95
95
|
return false unless route.path.spec.to_s.start_with?(OasRails.config.api_path)
|
96
|
+
return false if ignore_custom_actions(route)
|
96
97
|
|
97
98
|
true
|
98
99
|
end
|
@@ -119,6 +120,27 @@ module OasRails
|
|
119
120
|
controller_class.instance_methods.include?(action_name.to_sym)
|
120
121
|
end
|
121
122
|
end
|
123
|
+
|
124
|
+
# Ignore user-specified paths in initializer configuration.
|
125
|
+
# Sanitize api_path by removing the "/" if it starts with that, and adding "/" if it ends without that.
|
126
|
+
# Support controller name only to ignore all controller actions.
|
127
|
+
# Support ignoring "controller#action"
|
128
|
+
# Ignoring "controller#action" AND "api_path/controller#action"
|
129
|
+
def ignore_custom_actions(route)
|
130
|
+
api_path = "#{OasRails.config.api_path.sub(%r{\A/}, '')}/".sub(%r{/+$}, '/')
|
131
|
+
ignored_actions = OasRails.config.ignored_actions.flat_map do |custom_route|
|
132
|
+
if custom_route.start_with?(api_path)
|
133
|
+
[custom_route]
|
134
|
+
else
|
135
|
+
["#{api_path}#{custom_route}", custom_route]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
controller_action = "#{route.defaults[:controller]}##{route.defaults[:action]}"
|
140
|
+
controller_only = route.defaults[:controller]
|
141
|
+
|
142
|
+
ignored_actions.include?(controller_action) || ignored_actions.include?(controller_only)
|
143
|
+
end
|
122
144
|
end
|
123
145
|
end
|
124
146
|
end
|
data/lib/oas_rails/version.rb
CHANGED
@@ -15,7 +15,7 @@ module OasRails
|
|
15
15
|
# @param text [String] The tag text to parse.
|
16
16
|
# @return [RequestBodyExampleTag] The parsed request body example tag object.
|
17
17
|
def parse_tag_with_request_body_example(tag_name, text)
|
18
|
-
description, _, hash = extract_description_type_and_content(text, process_content: true)
|
18
|
+
description, _, hash = extract_description_type_and_content(text, process_content: true, expresion: /^(.*?)\[([^\]]*)\](.*)$/m)
|
19
19
|
RequestBodyExampleTag.new(tag_name, description, content: hash)
|
20
20
|
end
|
21
21
|
|
@@ -52,8 +52,8 @@ module OasRails
|
|
52
52
|
# @param text [String] The text to parse.
|
53
53
|
# @param process_content [Boolean] Whether to evaluate the content as a hash.
|
54
54
|
# @return [Array] An array containing the description, type, and content or remaining text.
|
55
|
-
def extract_description_type_and_content(text, process_content: false)
|
56
|
-
match = text.match(
|
55
|
+
def extract_description_type_and_content(text, process_content: false, expresion: /^(.*?)\s*\[(.*)\]\s*(.*)$/)
|
56
|
+
match = text.match(expresion)
|
57
57
|
raise ArgumentError, "Invalid tag format: #{text}" if match.nil?
|
58
58
|
|
59
59
|
description = match[1].strip
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oas_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- a-chacon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: method_source
|