openapi_first 0.17.0 → 0.19.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 +10 -0
- data/Gemfile.lock +17 -14
- data/README.md +21 -2
- data/benchmarks/Gemfile.lock +5 -4
- data/lib/openapi_first/default_operation_resolver.rb +1 -3
- data/lib/openapi_first/operation.rb +2 -3
- data/lib/openapi_first/rack_responder.rb +35 -0
- data/lib/openapi_first/responder.rb +1 -1
- data/lib/openapi_first/version.rb +1 -1
- data/lib/openapi_first.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d09bae8b5126245d86fceeb81b2d0d46fb1a9e1cb10370527327edb3e370fe59
|
4
|
+
data.tar.gz: 2bd5e71bd8022506be07ab7c60b2740d490fc0f2a0995ded0f6a9c6dc4d165e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d7d449f19fe40c49ea701eb28aca2a140ec41a5efb5be7433a5a60d85376a139a18c772ff34f211fbfb02e557ddddfdfad8ca547a695cb849bd62b69015775d
|
7
|
+
data.tar.gz: 6693234aab12e85893fedfa831ff21c831f00aa4040475a8a6e9fdbc5a2500e094f552ff1efef1c459af4df2eff21ad9f7ac4b6f93b2628f76d5f5169c4ad228
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.19.0
|
4
|
+
|
5
|
+
- Add `RackResponder`
|
6
|
+
|
7
|
+
- BREAKING CHANGE: Handler classes are now instantiated only once without any arguments and the same instance is called on each following call/request.
|
8
|
+
|
9
|
+
## 0.18.0
|
10
|
+
|
11
|
+
Yanked. No useful changes.
|
12
|
+
|
3
13
|
## 0.17.0
|
4
14
|
|
5
15
|
- BREAKING CHANGE: Use a Hash instead of named arguments for middleware options for better compatibility
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
openapi_first (0.
|
4
|
+
openapi_first (0.19.0)
|
5
5
|
deep_merge (>= 1.2.1)
|
6
6
|
hanami-router (= 2.0.alpha5)
|
7
7
|
hanami-utils (= 2.0.alpha3)
|
@@ -29,33 +29,34 @@ GEM
|
|
29
29
|
hanami-utils (2.0.0.alpha3)
|
30
30
|
concurrent-ruby (~> 1.0)
|
31
31
|
dry-transformer (~> 0.1)
|
32
|
-
hansi (0.2.
|
32
|
+
hansi (0.2.1)
|
33
|
+
json (2.6.2)
|
33
34
|
json_refs (0.1.7)
|
34
35
|
hana
|
35
|
-
json_schemer (0.2.
|
36
|
+
json_schemer (0.2.21)
|
36
37
|
ecma-re-validator (~> 0.3)
|
37
38
|
hana (~> 1.3)
|
38
39
|
regexp_parser (~> 2.0)
|
39
40
|
uri_template (~> 0.7)
|
40
41
|
method_source (1.0.0)
|
41
42
|
multi_json (1.15.0)
|
42
|
-
mustermann (1.1.
|
43
|
+
mustermann (1.1.2)
|
43
44
|
ruby2_keywords (~> 0.0.1)
|
44
|
-
mustermann-contrib (1.1.
|
45
|
+
mustermann-contrib (1.1.2)
|
45
46
|
hansi (~> 0.2.0)
|
46
|
-
mustermann (= 1.1.
|
47
|
+
mustermann (= 1.1.2)
|
47
48
|
parallel (1.22.1)
|
48
|
-
parser (3.1.
|
49
|
+
parser (3.1.2.0)
|
49
50
|
ast (~> 2.4.1)
|
50
51
|
pry (0.14.1)
|
51
52
|
coderay (~> 1.1)
|
52
53
|
method_source (~> 1.0)
|
53
|
-
rack (2.2.
|
54
|
+
rack (2.2.4)
|
54
55
|
rack-test (1.1.0)
|
55
56
|
rack (>= 1.0, < 3)
|
56
57
|
rainbow (3.1.1)
|
57
58
|
rake (13.0.6)
|
58
|
-
regexp_parser (2.
|
59
|
+
regexp_parser (2.5.0)
|
59
60
|
rexml (3.2.5)
|
60
61
|
rspec (3.11.0)
|
61
62
|
rspec-core (~> 3.11.0)
|
@@ -70,25 +71,27 @@ GEM
|
|
70
71
|
diff-lcs (>= 1.2.0, < 2.0)
|
71
72
|
rspec-support (~> 3.11.0)
|
72
73
|
rspec-support (3.11.0)
|
73
|
-
rubocop (1.
|
74
|
+
rubocop (1.32.0)
|
75
|
+
json (~> 2.3)
|
74
76
|
parallel (~> 1.10)
|
75
77
|
parser (>= 3.1.0.0)
|
76
78
|
rainbow (>= 2.2.2, < 4.0)
|
77
79
|
regexp_parser (>= 1.8, < 3.0)
|
78
|
-
rexml
|
79
|
-
rubocop-ast (>= 1.
|
80
|
+
rexml (>= 3.2.5, < 4.0)
|
81
|
+
rubocop-ast (>= 1.19.1, < 2.0)
|
80
82
|
ruby-progressbar (~> 1.7)
|
81
83
|
unicode-display_width (>= 1.4.0, < 3.0)
|
82
|
-
rubocop-ast (1.
|
84
|
+
rubocop-ast (1.19.1)
|
83
85
|
parser (>= 3.1.1.0)
|
84
86
|
ruby-progressbar (1.11.0)
|
85
87
|
ruby2_keywords (0.0.5)
|
86
|
-
unicode-display_width (2.
|
88
|
+
unicode-display_width (2.2.0)
|
87
89
|
uri_template (0.7.0)
|
88
90
|
|
89
91
|
PLATFORMS
|
90
92
|
arm64-darwin-21
|
91
93
|
x86_64-darwin-20
|
94
|
+
x86_64-linux
|
92
95
|
|
93
96
|
DEPENDENCIES
|
94
97
|
bundler (~> 2)
|
data/README.md
CHANGED
@@ -20,7 +20,8 @@ OpenapiFirst consists of these Rack middlewares:
|
|
20
20
|
|
21
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.
|
22
22
|
- [`OpenapiFirst::RequestValidation`](#OpenapiFirst::RequestValidation) – Validates the request against the API description and returns 400 if the request is invalid.
|
23
|
-
- [`OpenapiFirst::Responder`](#OpenapiFirst::Responder) calls the [handler](#handlers) found for the operation, sets the correct content-type and
|
23
|
+
- [`OpenapiFirst::Responder`](#OpenapiFirst::Responder) calls the [handler](#handlers) found for the operation, sets the correct content-type and serializes the response body to json if needed.
|
24
|
+
- [`OpenapiFirst::RackResponder`](#OpenapiFirst::RackResponder) calls the [handler](#handlers) found for the operation as a normal Rack application (`call(env)`) and returns the result as is.
|
24
25
|
- [`OpenapiFirst::ResponseValidation`](#OpenapiFirst::ResponseValidation) Validates the response and raises an exception if the response body is invalid.
|
25
26
|
|
26
27
|
## OpenapiFirst::Router
|
@@ -121,6 +122,24 @@ run OpenapiFirst::Responder
|
|
121
122
|
| `namespace:` | Optional. A class or module where to find the handler method. |
|
122
123
|
| `resolver:` | Optional. An object that responds to `#call(operation)` and returns a [handler](#handlers). By default this is an instance of [DefaultOperationResolver](#OpenapiFirst::DefaultOperationResolver) |
|
123
124
|
|
125
|
+
|
126
|
+
## OpenapiFirst::RackResponder
|
127
|
+
|
128
|
+
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 as a normal Rack application.
|
129
|
+
It does not not serialize objects as JSON or adds a content-type.
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
run OpenapiFirst::RackResponder
|
133
|
+
```
|
134
|
+
|
135
|
+
### Options
|
136
|
+
|
137
|
+
| Name | Description |
|
138
|
+
| :----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
139
|
+
| `namespace:` | Optional. A class or module where to find the handler method. |
|
140
|
+
| `resolver:` | Optional. An object that responds to `#call(operation)` and returns a [handler](#handlers). By default this is an instance of [DefaultOperationResolver](#OpenapiFirst::DefaultOperationResolver) |
|
141
|
+
|
142
|
+
|
124
143
|
### OpenapiFirst::DefaultOperationResolver
|
125
144
|
|
126
145
|
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.
|
@@ -129,7 +148,7 @@ It works like this:
|
|
129
148
|
|
130
149
|
- An operationId "create_pet" or "createPet" or "create pet" calls `MyApi.create_pet(params, response)`
|
131
150
|
- "some_things.create" calls: `MyApi::SomeThings.create(params, response)`
|
132
|
-
- "pets#create"
|
151
|
+
- "pets#create" instantiates the class once (`MyApi::Pets::Create.new) and calls it on every request(`instance.call(params, response)`).
|
133
152
|
|
134
153
|
### Handlers
|
135
154
|
|
data/benchmarks/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
openapi_first (0.
|
4
|
+
openapi_first (0.19.0)
|
5
5
|
deep_merge (>= 1.2.1)
|
6
6
|
hanami-router (= 2.0.alpha5)
|
7
7
|
hanami-utils (= 2.0.alpha3)
|
@@ -72,7 +72,7 @@ GEM
|
|
72
72
|
json_refs (0.1.7)
|
73
73
|
hana
|
74
74
|
json_schema (0.21.0)
|
75
|
-
json_schemer (0.2.
|
75
|
+
json_schemer (0.2.21)
|
76
76
|
ecma-re-validator (~> 0.3)
|
77
77
|
hana (~> 1.3)
|
78
78
|
regexp_parser (~> 2.0)
|
@@ -88,12 +88,12 @@ GEM
|
|
88
88
|
mustermann-grape (1.0.1)
|
89
89
|
mustermann (>= 1.0.0)
|
90
90
|
openapi_parser (0.15.0)
|
91
|
-
rack (2.2.3)
|
91
|
+
rack (2.2.3.1)
|
92
92
|
rack-accept (0.4.5)
|
93
93
|
rack (>= 0.4)
|
94
94
|
rack-protection (2.2.0)
|
95
95
|
rack
|
96
|
-
regexp_parser (2.
|
96
|
+
regexp_parser (2.5.0)
|
97
97
|
roda (3.54.0)
|
98
98
|
rack
|
99
99
|
ruby2_keywords (0.0.5)
|
@@ -113,6 +113,7 @@ GEM
|
|
113
113
|
|
114
114
|
PLATFORMS
|
115
115
|
arm64-darwin-21
|
116
|
+
x86_64-linux
|
116
117
|
|
117
118
|
DEPENDENCIES
|
118
119
|
benchmark-ips
|
@@ -37,9 +37,7 @@ module OpenapiFirst
|
|
37
37
|
module_name, klass_name = name.split('#')
|
38
38
|
const = find_const(@namespace, module_name)
|
39
39
|
klass = find_const(const, klass_name)
|
40
|
-
|
41
|
-
|
42
|
-
->(params, res) { klass.new(params.env).call(params, res) }
|
40
|
+
klass.new
|
43
41
|
end
|
44
42
|
|
45
43
|
def find_const(parent, name)
|
@@ -47,9 +47,8 @@ module OpenapiFirst
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
def
|
51
|
-
|
52
|
-
content.keys[0] if content
|
50
|
+
def content_types_for(status)
|
51
|
+
response_for(status)['content']&.keys
|
53
52
|
end
|
54
53
|
|
55
54
|
def response_schema_for(status, content_type)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rack'
|
4
|
+
require 'multi_json'
|
5
|
+
require_relative 'inbox'
|
6
|
+
require_relative 'default_operation_resolver'
|
7
|
+
|
8
|
+
module OpenapiFirst
|
9
|
+
class RackResponder
|
10
|
+
def initialize(namespace: nil, resolver: nil)
|
11
|
+
@resolver = resolver || DefaultOperationResolver.new(namespace)
|
12
|
+
@namespace = namespace
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
operation = env[OpenapiFirst::OPERATION]
|
17
|
+
find_handler(operation)&.call(env)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def find_handler(operation)
|
23
|
+
handler = @resolver.call(operation)
|
24
|
+
raise NotImplementedError, "Could not find handler for #{operation.name}" unless handler
|
25
|
+
|
26
|
+
handler
|
27
|
+
end
|
28
|
+
|
29
|
+
def serialize(result)
|
30
|
+
return result if result.is_a?(String)
|
31
|
+
|
32
|
+
MultiJson.dump(result)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -18,7 +18,7 @@ module OpenapiFirst
|
|
18
18
|
handler = find_handler(operation)
|
19
19
|
result = handler.call(env[INBOX], res)
|
20
20
|
res.write serialize(result) if result && res.body.empty?
|
21
|
-
res[Rack::CONTENT_TYPE] ||= operation.
|
21
|
+
res[Rack::CONTENT_TYPE] ||= operation.content_types_for(res.status)&.first
|
22
22
|
res.finish
|
23
23
|
end
|
24
24
|
|
data/lib/openapi_first.rb
CHANGED
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.19.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-
|
11
|
+
date: 2022-08-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deep_merge
|
@@ -217,6 +217,7 @@ files:
|
|
217
217
|
- lib/openapi_first/definition.rb
|
218
218
|
- lib/openapi_first/inbox.rb
|
219
219
|
- lib/openapi_first/operation.rb
|
220
|
+
- lib/openapi_first/rack_responder.rb
|
220
221
|
- lib/openapi_first/request_validation.rb
|
221
222
|
- lib/openapi_first/responder.rb
|
222
223
|
- lib/openapi_first/response_object.rb
|