openapi_first 0.14.3 → 0.15.0
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 +4 -0
- data/Gemfile.lock +26 -26
- data/README.md +27 -24
- data/benchmarks/Gemfile +1 -1
- data/benchmarks/Gemfile.lock +15 -17
- data/lib/openapi_first/operation.rb +1 -0
- data/lib/openapi_first/request_validation.rb +3 -1
- data/lib/openapi_first/schema_validation.rb +1 -0
- data/lib/openapi_first/version.rb +1 -1
- data/openapi_first.gemspec +2 -2
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c24075e5a05299387bba14bb16f931cf5e0f6cad58f0b0af04603ceb568dd78
|
4
|
+
data.tar.gz: 6e3eba2165048d139af385e736320157d6332f307d1cf99afe25172d5d48910d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65b51042f045570f3f357108aee08519be8e0f0b0ca2b997fa4ba3bbb49bd4febb98a28efb624f6cacd41074383c7b8920748c2997fe5d943108d3d72db5194e
|
7
|
+
data.tar.gz: 9188f1624b57d2eb5eea004bef5b086037681603a7dc788b1810faa42b44005360663326d81aa53ba549442c8667fef6b4830dfc542f7f39e77c011db25f01f2
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
openapi_first (0.
|
4
|
+
openapi_first (0.15.0)
|
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
8
|
json_refs (>= 0.1.7)
|
9
9
|
json_schemer (~> 0.2.16)
|
10
10
|
multi_json (~> 1.14)
|
@@ -16,11 +16,11 @@ GEM
|
|
16
16
|
ast (2.4.2)
|
17
17
|
coderay (1.1.3)
|
18
18
|
concurrent-ruby (1.1.9)
|
19
|
-
deep_merge (1.2.
|
20
|
-
diff-lcs (1.
|
19
|
+
deep_merge (1.2.2)
|
20
|
+
diff-lcs (1.5.0)
|
21
21
|
dry-transformer (0.1.1)
|
22
|
-
ecma-re-validator (0.
|
23
|
-
regexp_parser (~> 2.
|
22
|
+
ecma-re-validator (0.4.0)
|
23
|
+
regexp_parser (~> 2.2)
|
24
24
|
hana (1.3.7)
|
25
25
|
hanami-router (2.0.0.alpha5)
|
26
26
|
mustermann (~> 1.0)
|
@@ -45,7 +45,7 @@ GEM
|
|
45
45
|
hansi (~> 0.2.0)
|
46
46
|
mustermann (= 1.1.1)
|
47
47
|
parallel (1.21.0)
|
48
|
-
parser (3.0.
|
48
|
+
parser (3.1.0.0)
|
49
49
|
ast (~> 2.4.1)
|
50
50
|
pry (0.14.1)
|
51
51
|
coderay (~> 1.1)
|
@@ -53,33 +53,33 @@ GEM
|
|
53
53
|
rack (2.2.3)
|
54
54
|
rack-test (1.1.0)
|
55
55
|
rack (>= 1.0, < 3)
|
56
|
-
rainbow (3.
|
56
|
+
rainbow (3.1.1)
|
57
57
|
rake (13.0.6)
|
58
|
-
regexp_parser (2.
|
58
|
+
regexp_parser (2.2.1)
|
59
59
|
rexml (3.2.5)
|
60
|
-
rspec (3.
|
61
|
-
rspec-core (~> 3.
|
62
|
-
rspec-expectations (~> 3.
|
63
|
-
rspec-mocks (~> 3.
|
64
|
-
rspec-core (3.
|
65
|
-
rspec-support (~> 3.
|
66
|
-
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)
|
67
67
|
diff-lcs (>= 1.2.0, < 2.0)
|
68
|
-
rspec-support (~> 3.
|
69
|
-
rspec-mocks (3.
|
68
|
+
rspec-support (~> 3.11.0)
|
69
|
+
rspec-mocks (3.11.0)
|
70
70
|
diff-lcs (>= 1.2.0, < 2.0)
|
71
|
-
rspec-support (~> 3.
|
72
|
-
rspec-support (3.
|
73
|
-
rubocop (1.
|
71
|
+
rspec-support (~> 3.11.0)
|
72
|
+
rspec-support (3.11.0)
|
73
|
+
rubocop (1.25.1)
|
74
74
|
parallel (~> 1.10)
|
75
|
-
parser (>= 3.
|
75
|
+
parser (>= 3.1.0.0)
|
76
76
|
rainbow (>= 2.2.2, < 4.0)
|
77
77
|
regexp_parser (>= 1.8, < 3.0)
|
78
78
|
rexml
|
79
|
-
rubocop-ast (>= 1.
|
79
|
+
rubocop-ast (>= 1.15.1, < 2.0)
|
80
80
|
ruby-progressbar (~> 1.7)
|
81
81
|
unicode-display_width (>= 1.4.0, < 3.0)
|
82
|
-
rubocop-ast (1.
|
82
|
+
rubocop-ast (1.15.2)
|
83
83
|
parser (>= 3.0.1.1)
|
84
84
|
ruby-progressbar (1.11.0)
|
85
85
|
ruby2_keywords (0.0.5)
|
@@ -99,4 +99,4 @@ DEPENDENCIES
|
|
99
99
|
rubocop
|
100
100
|
|
101
101
|
BUNDLED WITH
|
102
|
-
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
|
|
data/benchmarks/Gemfile
CHANGED
data/benchmarks/Gemfile.lock
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
openapi_first (0.
|
4
|
+
openapi_first (0.15.0)
|
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
8
|
json_refs (>= 0.1.7)
|
9
9
|
json_schemer (~> 0.2.16)
|
10
10
|
multi_json (~> 1.14)
|
@@ -13,13 +13,12 @@ PATH
|
|
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
|
-
benchmark-ips (2.9.2)
|
21
|
+
benchmark-ips (2.9.3)
|
23
22
|
benchmark-memory (0.2.0)
|
24
23
|
memory_profiler (~> 1)
|
25
24
|
builder (3.2.4)
|
@@ -28,8 +27,8 @@ GEM
|
|
28
27
|
openapi_parser (>= 0.11.1, < 1.0)
|
29
28
|
rack (>= 1.5)
|
30
29
|
concurrent-ruby (1.1.9)
|
31
|
-
deep_merge (1.2.
|
32
|
-
dry-configurable (0.
|
30
|
+
deep_merge (1.2.2)
|
31
|
+
dry-configurable (0.14.0)
|
33
32
|
concurrent-ruby (~> 1.0)
|
34
33
|
dry-core (~> 0.6)
|
35
34
|
dry-container (0.9.0)
|
@@ -48,9 +47,9 @@ GEM
|
|
48
47
|
dry-core (~> 0.5, >= 0.5)
|
49
48
|
dry-inflector (~> 0.1, >= 0.1.2)
|
50
49
|
dry-logic (~> 1.0, >= 1.0.2)
|
51
|
-
ecma-re-validator (0.
|
52
|
-
regexp_parser (~> 2.
|
53
|
-
grape (1.6.
|
50
|
+
ecma-re-validator (0.4.0)
|
51
|
+
regexp_parser (~> 2.2)
|
52
|
+
grape (1.6.2)
|
54
53
|
activesupport
|
55
54
|
builder
|
56
55
|
dry-types (>= 1.1)
|
@@ -64,11 +63,11 @@ GEM
|
|
64
63
|
mustermann (~> 1.0)
|
65
64
|
mustermann-contrib (~> 1.0)
|
66
65
|
rack (~> 2.0)
|
67
|
-
hanami-utils (2.0.0.
|
66
|
+
hanami-utils (2.0.0.alpha6)
|
68
67
|
concurrent-ruby (~> 1.0)
|
69
68
|
dry-transformer (~> 0.1)
|
70
69
|
hansi (0.2.0)
|
71
|
-
i18n (1.
|
70
|
+
i18n (1.9.1)
|
72
71
|
concurrent-ruby (~> 1.0)
|
73
72
|
json_refs (0.1.7)
|
74
73
|
hana
|
@@ -79,7 +78,7 @@ GEM
|
|
79
78
|
regexp_parser (~> 2.0)
|
80
79
|
uri_template (~> 0.7)
|
81
80
|
memory_profiler (1.0.0)
|
82
|
-
minitest (5.
|
81
|
+
minitest (5.15.0)
|
83
82
|
multi_json (1.15.0)
|
84
83
|
mustermann (1.1.1)
|
85
84
|
ruby2_keywords (~> 0.0.1)
|
@@ -94,7 +93,7 @@ GEM
|
|
94
93
|
rack (>= 0.4)
|
95
94
|
rack-protection (2.1.0)
|
96
95
|
rack
|
97
|
-
regexp_parser (2.
|
96
|
+
regexp_parser (2.2.1)
|
98
97
|
ruby2_keywords (0.0.5)
|
99
98
|
seg (1.2.0)
|
100
99
|
sinatra (2.1.0)
|
@@ -109,7 +108,6 @@ GEM
|
|
109
108
|
tzinfo (2.0.4)
|
110
109
|
concurrent-ruby (~> 1.0)
|
111
110
|
uri_template (0.7.0)
|
112
|
-
zeitwerk (2.5.1)
|
113
111
|
|
114
112
|
PLATFORMS
|
115
113
|
x86_64-darwin-20
|
@@ -120,7 +118,7 @@ DEPENDENCIES
|
|
120
118
|
committee
|
121
119
|
grape
|
122
120
|
hanami-api
|
123
|
-
hanami-router (~> 2.0.0.
|
121
|
+
hanami-router (~> 2.0.0.alpha5)
|
124
122
|
multi_json
|
125
123
|
openapi_first!
|
126
124
|
sinatra
|
@@ -105,8 +105,10 @@ module OpenapiFirst
|
|
105
105
|
return unless schema
|
106
106
|
|
107
107
|
params = filtered_params(schema.raw_schema, params)
|
108
|
-
|
108
|
+
params = Utils.deep_stringify(params)
|
109
|
+
errors = schema.validate(params)
|
109
110
|
halt_with_error(400, serialize_query_parameter_errors(errors)) if errors.any?
|
111
|
+
params = Utils.deep_symbolize(params)
|
110
112
|
env[PARAMETERS] = params
|
111
113
|
env[INBOX].merge! params
|
112
114
|
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/openapi_first.gemspec
CHANGED
@@ -35,8 +35,8 @@ 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
40
|
spec.add_runtime_dependency 'json_refs', '>= 0.1.7'
|
41
41
|
spec.add_runtime_dependency 'json_schemer', '~> 0.2.16'
|
42
42
|
spec.add_runtime_dependency 'multi_json', '~> 1.14'
|
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.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Haller
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-02-
|
11
|
+
date: 2022-02-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deep_merge
|
@@ -30,28 +30,28 @@ 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
56
|
name: json_refs
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -243,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
243
243
|
- !ruby/object:Gem::Version
|
244
244
|
version: '0'
|
245
245
|
requirements: []
|
246
|
-
rubygems_version: 3.
|
246
|
+
rubygems_version: 3.3.3
|
247
247
|
signing_key:
|
248
248
|
specification_version: 4
|
249
249
|
summary: Implement REST APIs based on OpenApi.
|