openapi_first 0.14.1 → 0.16.0.beta1
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 +4 -4
- data/CHANGELOG.md +40 -1
- data/Gemfile.lock +31 -59
- data/README.md +31 -24
- data/benchmarks/Gemfile +1 -1
- data/benchmarks/Gemfile.lock +23 -40
- data/benchmarks/apps/committee.ru +1 -1
- data/benchmarks/apps/committee_with_response_validation.ru +29 -0
- data/benchmarks/apps/committee_with_sinatra.ru +31 -0
- data/benchmarks/apps/openapi.yaml +14 -14
- data/benchmarks/apps/openapi_first_with_hanami_api.ru +26 -0
- data/benchmarks/apps/openapi_first_with_response_validation.ru +22 -0
- data/lib/openapi_first/app.rb +0 -1
- data/lib/openapi_first/operation.rb +1 -1
- data/lib/openapi_first/request_validation.rb +7 -4
- data/lib/openapi_first/responder.rb +1 -0
- data/lib/openapi_first/response_object.rb +0 -1
- data/lib/openapi_first/response_validation.rb +1 -2
- data/lib/openapi_first/response_validator.rb +1 -3
- data/lib/openapi_first/router.rb +5 -8
- data/lib/openapi_first/schema_validation.rb +1 -0
- data/lib/openapi_first/version.rb +1 -1
- data/lib/openapi_first.rb +14 -12
- data/openapi_first.gemspec +6 -3
- metadata +25 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f46ad8751619914fa7b387ecb8a0178e67a7ba070e863321463f7ae1097e250
|
4
|
+
data.tar.gz: 5961b6bff590f957a8908d62b3c87bd65438dbdfe055020c61739af2862b06cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e08b5d1b12f3379ef2f28ab98da925a43c7adc69ea617c305dedb06fbe63e7843cf0d861cd32d7942f7770b4f7ac9bb2762ffb179374fd15deff2b86f64899f
|
7
|
+
data.tar.gz: ac406a2a868a44b8cfb8d54a71b5c4fb1d1078f666c6f3ee683a191c83c090a8312f59bd399e089edb4062d309ca98df02ee8b2078a445c1e3b16e5e19cfd462
|
data/CHANGELOG.md
CHANGED
@@ -1,42 +1,68 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## Unreleased
|
4
|
+
|
5
|
+
- Use a Hash instead of named arguments for middleware options for better compatibility
|
6
|
+
|
7
|
+
## 0.15.0
|
8
|
+
|
9
|
+
- Populate default parameter values
|
10
|
+
|
11
|
+
## 0.14.3
|
12
|
+
|
13
|
+
- Use json_refs to resolve OpenAPI file. This removes oas_parser and ActiveSupport from list of dependencies
|
14
|
+
|
15
|
+
## 0.14.2
|
16
|
+
|
17
|
+
- Empty query parameters are parsed and request validation returns 400 if an empty string is not allowed. Note that this does not look at `allowEmptyValue` in any way, because allowEmptyValue is deprecated.
|
3
18
|
|
4
19
|
## 0.14.1
|
20
|
+
|
5
21
|
- Bugfix: Don't mix path- and operation-level parameters for request validation
|
6
22
|
|
7
23
|
## 0.14.0
|
24
|
+
|
8
25
|
- Handle custom x-handler field in the API description to find a handler method not based on operationId
|
9
26
|
- Add `resolver` option to provide a custom resolver to find a handler method
|
10
27
|
|
11
28
|
## 0.13.3
|
29
|
+
|
12
30
|
- Better error message if string does not match format
|
13
31
|
- readOnly and writeOnly just works when used inside allOf
|
14
32
|
|
15
33
|
## 0.13.2
|
34
|
+
|
16
35
|
- Return indicator (`source: { parameter: 'list/1' }`) in error response body when array item in query parameter is invalid
|
17
36
|
|
18
37
|
## 0.13.0
|
38
|
+
|
19
39
|
- Add support for arrays in query parameters (style: form, explode: false)
|
20
40
|
- Remove warning when handler is not implemented
|
21
41
|
|
22
42
|
## 0.12.5
|
43
|
+
|
23
44
|
- Add `not_found: :continue` option to Router to make it do nothing if request is unknown
|
24
45
|
|
25
46
|
## 0.12.4
|
47
|
+
|
26
48
|
- content-type is found while ignoring additional content-type parameters (`application/json` is found when request/response content-type is `application/json; charset=UTF8`)
|
27
49
|
- Support wildcard mime-types when finding the content-type
|
28
50
|
|
29
51
|
## 0.12.3
|
52
|
+
|
30
53
|
- Add `response_validation:`, `router_raise_error` options to standalone mode.
|
31
54
|
|
32
55
|
## 0.12.2
|
56
|
+
|
33
57
|
- Allow response to have no media type object specified
|
34
58
|
|
35
59
|
## 0.12.1
|
60
|
+
|
36
61
|
- Fix response when handler returns 404 or 405
|
37
62
|
- Don't validate the response content if status is 204 (no content)
|
38
63
|
|
39
64
|
## 0.12.0
|
65
|
+
|
40
66
|
- Change `ResponseValidator` to raise an exception if it found a problem
|
41
67
|
- Params have symbolized keys now
|
42
68
|
- Remove `not_found` option from Router. Return 405 if HTTP verb is not allowed (via Hanami::Router)
|
@@ -48,6 +74,7 @@
|
|
48
74
|
- Add `Operation#name` that returns a human readable name for an operation
|
49
75
|
|
50
76
|
## 0.11.0
|
77
|
+
|
51
78
|
- Raise error if you forgot to add the Router middleware
|
52
79
|
- Make OpenapiFirst.app raise an error in test env when request path is not specified
|
53
80
|
- Rename OperationResolver to Responder
|
@@ -56,48 +83,60 @@
|
|
56
83
|
- Move namespace option from Router to OperationResolver
|
57
84
|
|
58
85
|
## 0.10.2
|
86
|
+
|
59
87
|
- Return 400 if request body has invalid JSON ([issue](https://github.com/ahx/openapi_first/issues/73)) thanks Thomas Frütel
|
60
88
|
|
61
89
|
## 0.10.1
|
90
|
+
|
62
91
|
- Fix duplicated key in `required` when generating JSON schema for `some[thing]` parameters
|
63
92
|
|
64
93
|
## 0.10.0
|
94
|
+
|
65
95
|
- Add support for query parameters named `"some[thing]"` ([issue](https://github.com/ahx/openapi_first/issues/40))
|
66
96
|
|
67
97
|
## 0.9.0
|
98
|
+
|
68
99
|
- Make request validation usable standalone
|
69
100
|
|
70
101
|
## 0.8.0
|
102
|
+
|
71
103
|
- Add merged parameter and request body available to env at `env[OpenapiFirst::INBOX]` in request validation
|
72
104
|
- Path and query parameters with `type: boolean` now get converted to `true`/`false`
|
73
105
|
- Rename `OpenapiFirst::PARAMS` to `OpenapiFirst::PARAMETERS`
|
74
106
|
|
75
107
|
## 0.7.1
|
108
|
+
|
76
109
|
- Add missing `require` to work with new version of `oas_parser`
|
77
110
|
|
78
111
|
## 0.7.0
|
112
|
+
|
79
113
|
- Make use of hanami-router, because it's fast
|
80
114
|
- Remove option `allow_unknown_query_paramerters`
|
81
115
|
- Move the namespace option to Router
|
82
|
-
- Convert numeric path and query parameters
|
116
|
+
- Convert numeric path and query parameters to `Integer` or `Float`
|
83
117
|
- Pass the Rack env if your action class' initializers accepts an argument
|
84
118
|
- Respec rack's `env['SCRIPT_NAME']` in router
|
85
119
|
- Add MIT license
|
86
120
|
|
87
121
|
## 0.6.10
|
122
|
+
|
88
123
|
- Bugfix: params.env['unknown'] now returns `nil` as expected. Thanks @tristandruyen.
|
89
124
|
|
90
125
|
## 0.6.9
|
126
|
+
|
91
127
|
- Removed radix tree, because of a bug (https://github.com/namusyaka/r2ree-ruby/issues/2)
|
92
128
|
|
93
129
|
## 0.6.8
|
130
|
+
|
94
131
|
- Performance: About 25% performance increase (i/s) with help of c++ based radix-tree and some optimizations
|
95
132
|
- Update dependencies
|
96
133
|
|
97
134
|
## 0.6.7
|
135
|
+
|
98
136
|
- Fix: version number of oas_parser
|
99
137
|
|
100
138
|
## 0.6.6
|
139
|
+
|
101
140
|
- Remove warnings for Ruby 2.7
|
102
141
|
|
103
142
|
## 0.6.5
|
data/Gemfile.lock
CHANGED
@@ -1,121 +1,93 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
openapi_first (0.
|
4
|
+
openapi_first (0.16.0.beta1)
|
5
5
|
deep_merge (>= 1.2.1)
|
6
|
-
hanami-router (~> 2.0.
|
7
|
-
hanami-utils (~> 2.0.
|
6
|
+
hanami-router (~> 2.0.alpha5)
|
7
|
+
hanami-utils (~> 2.0.alpha3)
|
8
|
+
json_refs (>= 0.1.7)
|
8
9
|
json_schemer (~> 0.2.16)
|
9
10
|
multi_json (~> 1.14)
|
10
|
-
oas_parser (~> 0.25.1)
|
11
11
|
rack (~> 2.2)
|
12
12
|
|
13
13
|
GEM
|
14
14
|
remote: https://rubygems.org/
|
15
15
|
specs:
|
16
|
-
activesupport (6.1.4.1)
|
17
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
18
|
-
i18n (>= 1.6, < 2)
|
19
|
-
minitest (>= 5.1)
|
20
|
-
tzinfo (~> 2.0)
|
21
|
-
zeitwerk (~> 2.3)
|
22
|
-
addressable (2.8.0)
|
23
|
-
public_suffix (>= 2.0.2, < 5.0)
|
24
16
|
ast (2.4.2)
|
25
|
-
builder (3.2.4)
|
26
17
|
coderay (1.1.3)
|
27
18
|
concurrent-ruby (1.1.9)
|
28
|
-
deep_merge (1.2.
|
29
|
-
diff-lcs (1.
|
19
|
+
deep_merge (1.2.2)
|
20
|
+
diff-lcs (1.5.0)
|
30
21
|
dry-transformer (0.1.1)
|
31
|
-
ecma-re-validator (0.
|
32
|
-
regexp_parser (~> 2.
|
22
|
+
ecma-re-validator (0.4.0)
|
23
|
+
regexp_parser (~> 2.2)
|
33
24
|
hana (1.3.7)
|
34
25
|
hanami-router (2.0.0.alpha5)
|
35
26
|
mustermann (~> 1.0)
|
36
27
|
mustermann-contrib (~> 1.0)
|
37
28
|
rack (~> 2.0)
|
38
|
-
hanami-utils (2.0.0.
|
29
|
+
hanami-utils (2.0.0.alpha3)
|
39
30
|
concurrent-ruby (~> 1.0)
|
40
31
|
dry-transformer (~> 0.1)
|
41
32
|
hansi (0.2.0)
|
42
|
-
|
43
|
-
|
44
|
-
concurrent-ruby (~> 1.0)
|
33
|
+
json_refs (0.1.7)
|
34
|
+
hana
|
45
35
|
json_schemer (0.2.18)
|
46
36
|
ecma-re-validator (~> 0.3)
|
47
37
|
hana (~> 1.3)
|
48
38
|
regexp_parser (~> 2.0)
|
49
39
|
uri_template (~> 0.7)
|
50
40
|
method_source (1.0.0)
|
51
|
-
mini_portile2 (2.6.1)
|
52
|
-
minitest (5.14.4)
|
53
41
|
multi_json (1.15.0)
|
54
42
|
mustermann (1.1.1)
|
55
43
|
ruby2_keywords (~> 0.0.1)
|
56
44
|
mustermann-contrib (1.1.1)
|
57
45
|
hansi (~> 0.2.0)
|
58
46
|
mustermann (= 1.1.1)
|
59
|
-
nokogiri (1.12.5)
|
60
|
-
mini_portile2 (~> 2.6.1)
|
61
|
-
racc (~> 1.4)
|
62
|
-
oas_parser (0.25.4)
|
63
|
-
activesupport (>= 4.0.0)
|
64
|
-
addressable (~> 2.3)
|
65
|
-
builder (~> 3.2.3)
|
66
|
-
deep_merge (~> 1.2.1)
|
67
|
-
hash-deep-merge
|
68
|
-
mustermann-contrib (~> 1.1.1)
|
69
|
-
nokogiri
|
70
47
|
parallel (1.21.0)
|
71
|
-
parser (3.0.
|
48
|
+
parser (3.1.0.0)
|
72
49
|
ast (~> 2.4.1)
|
73
50
|
pry (0.14.1)
|
74
51
|
coderay (~> 1.1)
|
75
52
|
method_source (~> 1.0)
|
76
|
-
public_suffix (4.0.6)
|
77
|
-
racc (1.5.2)
|
78
53
|
rack (2.2.3)
|
79
54
|
rack-test (1.1.0)
|
80
55
|
rack (>= 1.0, < 3)
|
81
|
-
rainbow (3.
|
56
|
+
rainbow (3.1.1)
|
82
57
|
rake (13.0.6)
|
83
|
-
regexp_parser (2.
|
58
|
+
regexp_parser (2.2.1)
|
84
59
|
rexml (3.2.5)
|
85
|
-
rspec (3.
|
86
|
-
rspec-core (~> 3.
|
87
|
-
rspec-expectations (~> 3.
|
88
|
-
rspec-mocks (~> 3.
|
89
|
-
rspec-core (3.
|
90
|
-
rspec-support (~> 3.
|
91
|
-
rspec-expectations (3.
|
60
|
+
rspec (3.11.0)
|
61
|
+
rspec-core (~> 3.11.0)
|
62
|
+
rspec-expectations (~> 3.11.0)
|
63
|
+
rspec-mocks (~> 3.11.0)
|
64
|
+
rspec-core (3.11.0)
|
65
|
+
rspec-support (~> 3.11.0)
|
66
|
+
rspec-expectations (3.11.0)
|
92
67
|
diff-lcs (>= 1.2.0, < 2.0)
|
93
|
-
rspec-support (~> 3.
|
94
|
-
rspec-mocks (3.
|
68
|
+
rspec-support (~> 3.11.0)
|
69
|
+
rspec-mocks (3.11.0)
|
95
70
|
diff-lcs (>= 1.2.0, < 2.0)
|
96
|
-
rspec-support (~> 3.
|
97
|
-
rspec-support (3.
|
98
|
-
rubocop (1.
|
71
|
+
rspec-support (~> 3.11.0)
|
72
|
+
rspec-support (3.11.0)
|
73
|
+
rubocop (1.25.1)
|
99
74
|
parallel (~> 1.10)
|
100
|
-
parser (>= 3.
|
75
|
+
parser (>= 3.1.0.0)
|
101
76
|
rainbow (>= 2.2.2, < 4.0)
|
102
77
|
regexp_parser (>= 1.8, < 3.0)
|
103
78
|
rexml
|
104
|
-
rubocop-ast (>= 1.
|
79
|
+
rubocop-ast (>= 1.15.1, < 2.0)
|
105
80
|
ruby-progressbar (~> 1.7)
|
106
81
|
unicode-display_width (>= 1.4.0, < 3.0)
|
107
|
-
rubocop-ast (1.
|
82
|
+
rubocop-ast (1.15.2)
|
108
83
|
parser (>= 3.0.1.1)
|
109
84
|
ruby-progressbar (1.11.0)
|
110
85
|
ruby2_keywords (0.0.5)
|
111
|
-
tzinfo (2.0.4)
|
112
|
-
concurrent-ruby (~> 1.0)
|
113
86
|
unicode-display_width (2.1.0)
|
114
87
|
uri_template (0.7.0)
|
115
|
-
zeitwerk (2.4.2)
|
116
88
|
|
117
89
|
PLATFORMS
|
118
|
-
|
90
|
+
x86_64-darwin-20
|
119
91
|
|
120
92
|
DEPENDENCIES
|
121
93
|
bundler (~> 2)
|
@@ -127,4 +99,4 @@ DEPENDENCIES
|
|
127
99
|
rubocop
|
128
100
|
|
129
101
|
BUNDLED WITH
|
130
|
-
2.
|
102
|
+
2.3.7
|
data/README.md
CHANGED
@@ -15,6 +15,7 @@ This gem is inspired by [committee](https://github.com/interagent/committee) (Ru
|
|
15
15
|
Here's a [comparison between committee and openapi_first](https://gist.github.com/ahx/1538c31f0652f459861713b5259e366a).
|
16
16
|
|
17
17
|
## Rack middlewares
|
18
|
+
|
18
19
|
OpenapiFirst consists of these Rack middlewares:
|
19
20
|
|
20
21
|
- [`OpenapiFirst::Router`](#OpenapiFirst::Router) – Finds the OpenAPI operation for the current request or returns 404 if no operation was found. This can be customized.
|
@@ -23,6 +24,7 @@ OpenapiFirst consists of these Rack middlewares:
|
|
23
24
|
- [`OpenapiFirst::ResponseValidation`](#OpenapiFirst::ResponseValidation) Validates the response and raises an exception if the response body is invalid.
|
24
25
|
|
25
26
|
## OpenapiFirst::Router
|
27
|
+
|
26
28
|
You always have to add this middleware first in order to make the other middlewares work.
|
27
29
|
|
28
30
|
```ruby
|
@@ -33,11 +35,11 @@ This middleware adds `env[OpenapiFirst::OPERATION]` which holds an Operation obj
|
|
33
35
|
|
34
36
|
### Options and defaults
|
35
37
|
|
36
|
-
| Name
|
37
|
-
|
38
|
-
|
39
|
-
| `raise_error:`
|
40
|
-
| `not_found:`
|
38
|
+
| Name | Possible values | Description | Default |
|
39
|
+
| :------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
|
40
|
+
| `spec:` | | The spec loaded via `OpenapiFirst.load` | |
|
41
|
+
| `raise_error:` | `false`, `true` | If set to true the middleware raises `OpenapiFirst::NotFoundError` when a path or method was not found in the API description. This is useful during testing to spot an incomplete API description. | `false` (don't raise an exception) |
|
42
|
+
| `not_found:` | `:continue`, `:halt` | If set to `:continue` the middleware will not return 404 (405, 415), but just pass handling the request to the next middleware or application in the Rack stack. If combined with `raise_error: true` `raise_error` gets preference and an exception is raised. | `:halt` (return 4xx response) |
|
41
43
|
|
42
44
|
## OpenapiFirst::RequestValidation
|
43
45
|
|
@@ -47,12 +49,11 @@ This middleware returns a 400 status code with a body that describes the error i
|
|
47
49
|
use OpenapiFirst::RequestValidation
|
48
50
|
```
|
49
51
|
|
50
|
-
|
51
52
|
### Options and defaults
|
52
53
|
|
53
|
-
| Name
|
54
|
-
|
55
|
-
| `raise_error:`
|
54
|
+
| Name | Possible values | Description | Default |
|
55
|
+
| :------------- | --------------- | -------------------------------------------------------------------------------------------------- | ---------------------------------- |
|
56
|
+
| `raise_error:` | `false`, `true` | If set to true the middleware raises `OpenapiFirst::RequestInvalidError` instead of returning 4xx. | `false` (don't raise an exception) |
|
56
57
|
|
57
58
|
The error responses conform with [JSON:API](https://jsonapi.org).
|
58
59
|
|
@@ -110,17 +111,18 @@ Response validation fails if response body includes a property with `writeOnly:
|
|
110
111
|
This Rack endpoint maps the HTTP request to a method call based on the [operationId](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#operation-object) in your API description and calls it. Responder also adds a content-type to the response.
|
111
112
|
|
112
113
|
```ruby
|
113
|
-
run OpenapiFirst::Responder
|
114
|
+
run OpenapiFirst::Responder
|
114
115
|
```
|
115
116
|
|
116
117
|
### Options
|
117
|
-
| Name | Description
|
118
|
-
|:---|---|
|
119
|
-
| `namespace:` | Optional. A class or module where to find the handler method. |
|
120
|
-
| `resolver:` | Optional. An object that responds to `#call(operation)` and returns a [handler](#handlers). By default this is an instance of [DefaultOperationResolver](#OpenapiFirst::DefaultOperationResolver) |
|
121
118
|
|
119
|
+
| Name | Description |
|
120
|
+
| :----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
121
|
+
| `namespace:` | Optional. A class or module where to find the handler method. |
|
122
|
+
| `resolver:` | Optional. An object that responds to `#call(operation)` and returns a [handler](#handlers). By default this is an instance of [DefaultOperationResolver](#OpenapiFirst::DefaultOperationResolver) |
|
122
123
|
|
123
124
|
### OpenapiFirst::DefaultOperationResolver
|
125
|
+
|
124
126
|
This is the default way to look up a handler method for an operation. Handlers are always looked up in a namespace module that needs to be specified.
|
125
127
|
|
126
128
|
It works like this:
|
@@ -144,13 +146,15 @@ There are two ways to set the response body:
|
|
144
146
|
- Returning a value which will get converted to JSON
|
145
147
|
|
146
148
|
## OpenapiFirst::ResponseValidation
|
147
|
-
|
149
|
+
|
150
|
+
This middleware is especially useful when testing. It _always_ raises an error if the response is not valid.
|
148
151
|
|
149
152
|
```ruby
|
150
153
|
use OpenapiFirst::ResponseValidation if ENV['RACK_ENV'] == 'test'
|
151
154
|
```
|
152
155
|
|
153
156
|
## Standalone usage
|
157
|
+
|
154
158
|
Instead of composing these middlewares yourself you can use `OpenapiFirst.app`.
|
155
159
|
|
156
160
|
```ruby
|
@@ -181,15 +185,14 @@ The above will use the mentioned Rack middlewares to:
|
|
181
185
|
|
182
186
|
### Options and defaults
|
183
187
|
|
184
|
-
| Name
|
185
|
-
|
186
|
-
| `spec_path`
|
187
|
-
| `namespace:`
|
188
|
-
| `response_validation:`
|
189
|
-
| `router_raise_error:`
|
190
|
-
| `request_validation_raise_error:` | `true`, `false` | If set to true it raises an exception (subclass of `OpenapiFirst::Error` when a request is not valid.
|
191
|
-
| `resolver:`
|
192
|
-
|
188
|
+
| Name | Possible values | Description | Default |
|
189
|
+
| :-------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
190
|
+
| `spec_path` | | A filepath to an OpenAPI definition file. |
|
191
|
+
| `namespace:` | | A class or module where to find the handler methods. |
|
192
|
+
| `response_validation:` | `true`, `false` | If set to true it raises an exception if the response is invalid. This is useful during testing. | `false` |
|
193
|
+
| `router_raise_error:` | `true`, `false` | If set to true it raises an exception (subclass of `OpenapiFirst::Error` when a request path/method is not specified. This is useful during testing. | `false` |
|
194
|
+
| `request_validation_raise_error:` | `true`, `false` | If set to true it raises an exception (subclass of `OpenapiFirst::Error` when a request is not valid. | `false` |
|
195
|
+
| `resolver:` | | Option to customize finding the [handler](#handlers) method for an operation. See [OpenapiFirst::Responder](#OpenapiFirst::Responder) for details. |
|
193
196
|
|
194
197
|
Handler functions (`find_pet`) are called with two arguments:
|
195
198
|
|
@@ -289,6 +292,10 @@ Run `bundle exec rspec` to run the tests.
|
|
289
292
|
|
290
293
|
See `bundle exec rake -T` for rubygems related tasks.
|
291
294
|
|
295
|
+
## Benchmarks
|
296
|
+
|
297
|
+
[Results](https://gist.github.com/ahx/e6ffced58bd2e8d5baffb2f4d2c1f823)
|
298
|
+
|
292
299
|
### Run benchmarks
|
293
300
|
|
294
301
|
```sh
|
data/benchmarks/Gemfile
CHANGED
data/benchmarks/Gemfile.lock
CHANGED
@@ -1,37 +1,34 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
openapi_first (0.
|
4
|
+
openapi_first (0.16.0.beta1)
|
5
5
|
deep_merge (>= 1.2.1)
|
6
|
-
hanami-router (~> 2.0.
|
7
|
-
hanami-utils (~> 2.0.
|
6
|
+
hanami-router (~> 2.0.alpha5)
|
7
|
+
hanami-utils (~> 2.0.alpha3)
|
8
|
+
json_refs (>= 0.1.7)
|
8
9
|
json_schemer (~> 0.2.16)
|
9
10
|
multi_json (~> 1.14)
|
10
|
-
oas_parser (~> 0.25.1)
|
11
11
|
rack (~> 2.2)
|
12
12
|
|
13
13
|
GEM
|
14
14
|
remote: https://rubygems.org/
|
15
15
|
specs:
|
16
|
-
activesupport (
|
16
|
+
activesupport (7.0.2.2)
|
17
17
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
18
18
|
i18n (>= 1.6, < 2)
|
19
19
|
minitest (>= 5.1)
|
20
20
|
tzinfo (~> 2.0)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
benchmark-ips (2.9.1)
|
25
|
-
benchmark-memory (0.1.2)
|
26
|
-
memory_profiler (~> 0.9)
|
21
|
+
benchmark-ips (2.9.3)
|
22
|
+
benchmark-memory (0.2.0)
|
23
|
+
memory_profiler (~> 1)
|
27
24
|
builder (3.2.4)
|
28
25
|
committee (4.4.0)
|
29
26
|
json_schema (~> 0.14, >= 0.14.3)
|
30
27
|
openapi_parser (>= 0.11.1, < 1.0)
|
31
28
|
rack (>= 1.5)
|
32
29
|
concurrent-ruby (1.1.9)
|
33
|
-
deep_merge (1.2.
|
34
|
-
dry-configurable (0.
|
30
|
+
deep_merge (1.2.2)
|
31
|
+
dry-configurable (0.14.0)
|
35
32
|
concurrent-ruby (~> 1.0)
|
36
33
|
dry-core (~> 0.6)
|
37
34
|
dry-container (0.9.0)
|
@@ -50,9 +47,9 @@ GEM
|
|
50
47
|
dry-core (~> 0.5, >= 0.5)
|
51
48
|
dry-inflector (~> 0.1, >= 0.1.2)
|
52
49
|
dry-logic (~> 1.0, >= 1.0.2)
|
53
|
-
ecma-re-validator (0.
|
54
|
-
regexp_parser (~> 2.
|
55
|
-
grape (1.6.
|
50
|
+
ecma-re-validator (0.4.0)
|
51
|
+
regexp_parser (~> 2.2)
|
52
|
+
grape (1.6.2)
|
56
53
|
activesupport
|
57
54
|
builder
|
58
55
|
dry-types (>= 1.1)
|
@@ -66,22 +63,22 @@ GEM
|
|
66
63
|
mustermann (~> 1.0)
|
67
64
|
mustermann-contrib (~> 1.0)
|
68
65
|
rack (~> 2.0)
|
69
|
-
hanami-utils (2.0.0.
|
66
|
+
hanami-utils (2.0.0.alpha6)
|
70
67
|
concurrent-ruby (~> 1.0)
|
71
68
|
dry-transformer (~> 0.1)
|
72
69
|
hansi (0.2.0)
|
73
|
-
|
74
|
-
i18n (1.8.10)
|
70
|
+
i18n (1.9.1)
|
75
71
|
concurrent-ruby (~> 1.0)
|
72
|
+
json_refs (0.1.7)
|
73
|
+
hana
|
76
74
|
json_schema (0.21.0)
|
77
75
|
json_schemer (0.2.18)
|
78
76
|
ecma-re-validator (~> 0.3)
|
79
77
|
hana (~> 1.3)
|
80
78
|
regexp_parser (~> 2.0)
|
81
79
|
uri_template (~> 0.7)
|
82
|
-
memory_profiler (0.
|
83
|
-
|
84
|
-
minitest (5.14.4)
|
80
|
+
memory_profiler (1.0.0)
|
81
|
+
minitest (5.15.0)
|
85
82
|
multi_json (1.15.0)
|
86
83
|
mustermann (1.1.1)
|
87
84
|
ruby2_keywords (~> 0.0.1)
|
@@ -90,26 +87,13 @@ GEM
|
|
90
87
|
mustermann (= 1.1.1)
|
91
88
|
mustermann-grape (1.0.1)
|
92
89
|
mustermann (>= 1.0.0)
|
93
|
-
nokogiri (1.12.5)
|
94
|
-
mini_portile2 (~> 2.6.1)
|
95
|
-
racc (~> 1.4)
|
96
|
-
oas_parser (0.25.4)
|
97
|
-
activesupport (>= 4.0.0)
|
98
|
-
addressable (~> 2.3)
|
99
|
-
builder (~> 3.2.3)
|
100
|
-
deep_merge (~> 1.2.1)
|
101
|
-
hash-deep-merge
|
102
|
-
mustermann-contrib (~> 1.1.1)
|
103
|
-
nokogiri
|
104
90
|
openapi_parser (0.15.0)
|
105
|
-
public_suffix (4.0.6)
|
106
|
-
racc (1.5.2)
|
107
91
|
rack (2.2.3)
|
108
92
|
rack-accept (0.4.5)
|
109
93
|
rack (>= 0.4)
|
110
94
|
rack-protection (2.1.0)
|
111
95
|
rack
|
112
|
-
regexp_parser (2.
|
96
|
+
regexp_parser (2.2.1)
|
113
97
|
ruby2_keywords (0.0.5)
|
114
98
|
seg (1.2.0)
|
115
99
|
sinatra (2.1.0)
|
@@ -124,10 +108,9 @@ GEM
|
|
124
108
|
tzinfo (2.0.4)
|
125
109
|
concurrent-ruby (~> 1.0)
|
126
110
|
uri_template (0.7.0)
|
127
|
-
zeitwerk (2.4.2)
|
128
111
|
|
129
112
|
PLATFORMS
|
130
|
-
|
113
|
+
x86_64-darwin-20
|
131
114
|
|
132
115
|
DEPENDENCIES
|
133
116
|
benchmark-ips
|
@@ -135,11 +118,11 @@ DEPENDENCIES
|
|
135
118
|
committee
|
136
119
|
grape
|
137
120
|
hanami-api
|
138
|
-
hanami-router (~> 2.0.0.
|
121
|
+
hanami-router (~> 2.0.0.alpha5)
|
139
122
|
multi_json
|
140
123
|
openapi_first!
|
141
124
|
sinatra
|
142
125
|
syro
|
143
126
|
|
144
127
|
BUNDLED WITH
|
145
|
-
2.2.
|
128
|
+
2.2.28
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'multi_json'
|
4
|
+
require 'committee'
|
5
|
+
require 'hanami/api'
|
6
|
+
|
7
|
+
app = Class.new(Hanami::API) do
|
8
|
+
get '/hello/:id' do
|
9
|
+
json(hello: 'world', id: params.fetch(:id))
|
10
|
+
end
|
11
|
+
|
12
|
+
get '/hello' do
|
13
|
+
json([{ hello: 'world' }])
|
14
|
+
end
|
15
|
+
|
16
|
+
post '/hello' do
|
17
|
+
status 201
|
18
|
+
json(hello: 'world')
|
19
|
+
end
|
20
|
+
end.new
|
21
|
+
|
22
|
+
use Committee::Middleware::RequestValidation,
|
23
|
+
schema_path: File.absolute_path('./openapi.yaml', __dir__),
|
24
|
+
parse_response_by_content_type: true
|
25
|
+
|
26
|
+
use Committee::Middleware::ResponseValidation,
|
27
|
+
schema_path: File.absolute_path('./openapi.yaml', __dir__)
|
28
|
+
|
29
|
+
run app
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'multi_json'
|
4
|
+
require 'committee'
|
5
|
+
require 'sinatra'
|
6
|
+
|
7
|
+
class SinatraWithCommiteeExample < Sinatra::Base
|
8
|
+
set :environment, :production
|
9
|
+
|
10
|
+
get '/hello/:id' do
|
11
|
+
content_type :json
|
12
|
+
MultiJson.dump(hello: 'world', id: params.fetch('id'))
|
13
|
+
end
|
14
|
+
|
15
|
+
get '/hello' do
|
16
|
+
content_type :json
|
17
|
+
MultiJson.dump([{ hello: 'world' }])
|
18
|
+
end
|
19
|
+
|
20
|
+
post '/hello' do
|
21
|
+
content_type :json
|
22
|
+
status 201
|
23
|
+
MultiJson.dump(hello: 'world')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
use Committee::Middleware::RequestValidation,
|
28
|
+
schema_path: File.absolute_path('./openapi.yaml', __dir__),
|
29
|
+
parse_response_by_content_type: true
|
30
|
+
|
31
|
+
run SinatraWithCommiteeExample
|
@@ -28,15 +28,13 @@ paths:
|
|
28
28
|
content:
|
29
29
|
application/json:
|
30
30
|
schema:
|
31
|
-
type:
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
id:
|
39
|
-
type: string
|
31
|
+
type: object
|
32
|
+
required: [hello, id]
|
33
|
+
properties:
|
34
|
+
hello:
|
35
|
+
type: string
|
36
|
+
id:
|
37
|
+
type: string
|
40
38
|
/hello:
|
41
39
|
get:
|
42
40
|
operationId: find_things
|
@@ -61,11 +59,13 @@ paths:
|
|
61
59
|
content:
|
62
60
|
application/json:
|
63
61
|
schema:
|
64
|
-
type:
|
65
|
-
|
66
|
-
|
67
|
-
hello
|
68
|
-
|
62
|
+
type: array
|
63
|
+
items:
|
64
|
+
type: object
|
65
|
+
required: [hello]
|
66
|
+
properties:
|
67
|
+
hello:
|
68
|
+
type: string
|
69
69
|
default:
|
70
70
|
description: Error response
|
71
71
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'multi_json'
|
4
|
+
require 'openapi_first'
|
5
|
+
require 'hanami/api'
|
6
|
+
|
7
|
+
app = Class.new(Hanami::API) do
|
8
|
+
get '/hello/:id' do
|
9
|
+
json(hello: 'world', id: params.fetch(:id))
|
10
|
+
end
|
11
|
+
|
12
|
+
get '/hello' do
|
13
|
+
json([{ hello: 'world' }])
|
14
|
+
end
|
15
|
+
|
16
|
+
post '/hello' do
|
17
|
+
status 201
|
18
|
+
json(hello: 'world')
|
19
|
+
end
|
20
|
+
end.new
|
21
|
+
|
22
|
+
oas_path = File.absolute_path('./openapi.yaml', __dir__)
|
23
|
+
use OpenapiFirst::Router, spec: OpenapiFirst.load(oas_path)
|
24
|
+
use OpenapiFirst::RequestValidation
|
25
|
+
|
26
|
+
run app
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'multi_json'
|
4
|
+
require 'openapi_first'
|
5
|
+
|
6
|
+
namespace = Module.new do
|
7
|
+
def self.find_thing(params, _res)
|
8
|
+
{ hello: 'world', id: params.fetch(:id) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.find_things(_params, _res)
|
12
|
+
[{ hello: 'world' }]
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.create_thing(_params, res)
|
16
|
+
res.status = 201
|
17
|
+
{ hello: 'world' }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
oas_path = File.absolute_path('./openapi.yaml', __dir__)
|
22
|
+
run OpenapiFirst.app(oas_path, namespace: namespace, response_validation: true)
|
data/lib/openapi_first/app.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rack'
|
4
|
-
require 'json_schemer'
|
5
4
|
require 'multi_json'
|
6
5
|
require_relative 'inbox'
|
7
6
|
require_relative 'router_required'
|
@@ -11,9 +10,9 @@ module OpenapiFirst
|
|
11
10
|
class RequestValidation # rubocop:disable Metrics/ClassLength
|
12
11
|
prepend RouterRequired
|
13
12
|
|
14
|
-
def initialize(app,
|
13
|
+
def initialize(app, options = {})
|
15
14
|
@app = app
|
16
|
-
@raise = raise_error
|
15
|
+
@raise = options.fetch(:raise_error, false)
|
17
16
|
end
|
18
17
|
|
19
18
|
def call(env) # rubocop:disable Metrics/AbcSize
|
@@ -106,8 +105,10 @@ module OpenapiFirst
|
|
106
105
|
return unless schema
|
107
106
|
|
108
107
|
params = filtered_params(schema.raw_schema, params)
|
109
|
-
|
108
|
+
params = Utils.deep_stringify(params)
|
109
|
+
errors = schema.validate(params)
|
110
110
|
halt_with_error(400, serialize_query_parameter_errors(errors)) if errors.any?
|
111
|
+
params = Utils.deep_symbolize(params)
|
111
112
|
env[PARAMETERS] = params
|
112
113
|
env[INBOX].merge! params
|
113
114
|
end
|
@@ -142,6 +143,8 @@ module OpenapiFirst
|
|
142
143
|
end
|
143
144
|
|
144
145
|
def parse_array_parameter(value, schema)
|
146
|
+
return value if value.nil? || value.empty?
|
147
|
+
|
145
148
|
array = value.is_a?(Array) ? value : value.split(',')
|
146
149
|
return array unless schema['items']
|
147
150
|
|
data/lib/openapi_first/router.rb
CHANGED
@@ -2,21 +2,18 @@
|
|
2
2
|
|
3
3
|
require 'rack'
|
4
4
|
require 'hanami/router'
|
5
|
-
require_relative 'utils'
|
6
5
|
|
7
6
|
module OpenapiFirst
|
8
7
|
class Router
|
9
8
|
def initialize(
|
10
9
|
app,
|
11
|
-
|
12
|
-
raise_error: false,
|
13
|
-
not_found: :halt,
|
14
|
-
parent_app: nil
|
10
|
+
options
|
15
11
|
)
|
16
12
|
@app = app
|
17
|
-
@parent_app = parent_app
|
18
|
-
@raise = raise_error
|
19
|
-
@not_found = not_found
|
13
|
+
@parent_app = options.fetch(:parent_app, nil)
|
14
|
+
@raise = options.fetch(:raise_error, false)
|
15
|
+
@not_found = options.fetch(:not_found, :halt)
|
16
|
+
spec = options.fetch(:spec)
|
20
17
|
@filepath = spec.filepath
|
21
18
|
@router = build_router(spec.operations)
|
22
19
|
end
|
@@ -14,6 +14,7 @@ module OpenapiFirst
|
|
14
14
|
@schemer = JSONSchemer.schema(
|
15
15
|
schema,
|
16
16
|
keywords: custom_keywords,
|
17
|
+
insert_property_defaults: true,
|
17
18
|
before_property_validation: proc do |data, property, property_schema, parent|
|
18
19
|
convert_nullable(data, property, property_schema, parent)
|
19
20
|
end
|
data/lib/openapi_first.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'yaml'
|
4
|
-
require '
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
4
|
+
require 'json_refs'
|
5
|
+
require_relative 'openapi_first/definition'
|
6
|
+
require_relative 'openapi_first/version'
|
7
|
+
require_relative 'openapi_first/inbox'
|
8
|
+
require_relative 'openapi_first/router'
|
9
|
+
require_relative 'openapi_first/request_validation'
|
10
|
+
require_relative 'openapi_first/response_validator'
|
11
|
+
require_relative 'openapi_first/response_validation'
|
12
|
+
require_relative 'openapi_first/responder'
|
13
|
+
require_relative 'openapi_first/app'
|
14
14
|
|
15
15
|
module OpenapiFirst
|
16
16
|
OPERATION = 'openapi_first.operation'
|
@@ -24,8 +24,10 @@ module OpenapiFirst
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.load(spec_path, only: nil)
|
27
|
-
|
28
|
-
|
27
|
+
resolved = Dir.chdir(File.dirname(spec_path)) do
|
28
|
+
content = YAML.load_file(File.basename(spec_path))
|
29
|
+
JsonRefs.call(content, resolve_local_ref: true, resolve_file_ref: true)
|
30
|
+
end
|
29
31
|
resolved['paths'].filter!(&->(key, _) { only.call(key) }) if only
|
30
32
|
Definition.new(resolved, spec_path)
|
31
33
|
end
|
data/openapi_first.gemspec
CHANGED
@@ -35,15 +35,18 @@ Gem::Specification.new do |spec|
|
|
35
35
|
spec.required_ruby_version = '>= 2.6.0'
|
36
36
|
|
37
37
|
spec.add_runtime_dependency 'deep_merge', '>= 1.2.1'
|
38
|
-
spec.add_runtime_dependency 'hanami-router', '~> 2.0.
|
39
|
-
spec.add_runtime_dependency 'hanami-utils', '~> 2.0.
|
38
|
+
spec.add_runtime_dependency 'hanami-router', '~> 2.0.alpha5'
|
39
|
+
spec.add_runtime_dependency 'hanami-utils', '~> 2.0.alpha3'
|
40
|
+
spec.add_runtime_dependency 'json_refs', '>= 0.1.7'
|
40
41
|
spec.add_runtime_dependency 'json_schemer', '~> 0.2.16'
|
41
42
|
spec.add_runtime_dependency 'multi_json', '~> 1.14'
|
42
|
-
spec.add_runtime_dependency 'oas_parser', '~> 0.25.1'
|
43
43
|
spec.add_runtime_dependency 'rack', '~> 2.2'
|
44
44
|
|
45
45
|
spec.add_development_dependency 'bundler', '~> 2'
|
46
46
|
spec.add_development_dependency 'rack-test', '~> 1'
|
47
47
|
spec.add_development_dependency 'rake', '~> 13'
|
48
48
|
spec.add_development_dependency 'rspec', '~> 3'
|
49
|
+
spec.metadata = {
|
50
|
+
'rubygems_mfa_required' => 'true'
|
51
|
+
}
|
49
52
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openapi_first
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.16.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Haller
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deep_merge
|
@@ -30,70 +30,70 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.0.
|
33
|
+
version: 2.0.alpha5
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 2.0.
|
40
|
+
version: 2.0.alpha5
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: hanami-utils
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 2.0.
|
47
|
+
version: 2.0.alpha3
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 2.0.
|
54
|
+
version: 2.0.alpha3
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: json_refs
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
61
|
+
version: 0.1.7
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.
|
68
|
+
version: 0.1.7
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: json_schemer
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 0.2.16
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 0.2.16
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: multi_json
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
89
|
+
version: '1.14'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: '1.14'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rack
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -185,11 +185,15 @@ files:
|
|
185
185
|
- benchmarks/Gemfile
|
186
186
|
- benchmarks/Gemfile.lock
|
187
187
|
- benchmarks/apps/committee.ru
|
188
|
+
- benchmarks/apps/committee_with_response_validation.ru
|
189
|
+
- benchmarks/apps/committee_with_sinatra.ru
|
188
190
|
- benchmarks/apps/grape.ru
|
189
191
|
- benchmarks/apps/hanami_api.ru
|
190
192
|
- benchmarks/apps/hanami_router.ru
|
191
193
|
- benchmarks/apps/openapi.yaml
|
192
194
|
- benchmarks/apps/openapi_first.ru
|
195
|
+
- benchmarks/apps/openapi_first_with_hanami_api.ru
|
196
|
+
- benchmarks/apps/openapi_first_with_response_validation.ru
|
193
197
|
- benchmarks/apps/sinatra.ru
|
194
198
|
- benchmarks/apps/syro.ru
|
195
199
|
- benchmarks/benchmarks.rb
|
@@ -223,9 +227,7 @@ homepage: https://github.com/ahx/openapi_first
|
|
223
227
|
licenses:
|
224
228
|
- MIT
|
225
229
|
metadata:
|
226
|
-
|
227
|
-
source_code_uri: https://github.com/ahx/openapi_first
|
228
|
-
changelog_uri: https://github.com/ahx/openapi_first/blob/master/CHANGELOG.md
|
230
|
+
rubygems_mfa_required: 'true'
|
229
231
|
post_install_message:
|
230
232
|
rdoc_options: []
|
231
233
|
require_paths:
|
@@ -237,11 +239,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
237
239
|
version: 2.6.0
|
238
240
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
239
241
|
requirements:
|
240
|
-
- - "
|
242
|
+
- - ">"
|
241
243
|
- !ruby/object:Gem::Version
|
242
|
-
version:
|
244
|
+
version: 1.3.1
|
243
245
|
requirements: []
|
244
|
-
rubygems_version: 3.
|
246
|
+
rubygems_version: 3.3.3
|
245
247
|
signing_key:
|
246
248
|
specification_version: 4
|
247
249
|
summary: Implement REST APIs based on OpenApi.
|