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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a6e1915ef20b0c31bd58a5f0bbba3d91b9be2915c9c0e1598e085d4bea142a06
4
- data.tar.gz: 42c62a18aab203b1920adf1367cd9bc500c6e31b1e82fb8b4370ca34cedb372d
3
+ metadata.gz: d09bae8b5126245d86fceeb81b2d0d46fb1a9e1cb10370527327edb3e370fe59
4
+ data.tar.gz: 2bd5e71bd8022506be07ab7c60b2740d490fc0f2a0995ded0f6a9c6dc4d165e3
5
5
  SHA512:
6
- metadata.gz: a7985ff17cce925cb8ed24b47efaea39f4a2bef3a7f029de3edbef38a6ae555e57784d1346cfa0acbfd18b3d70124c4019dd0a5533990dccfcc408667b70b693
7
- data.tar.gz: 8e28e55faf6de5246ff87c0943f507c2f93afe4d96f5bbde423feb15607295e7888d25c4add8054ec90103a4305161366f72c8088d0d8f64e053f9ba6902b592
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.17.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.0)
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.20)
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.1)
43
+ mustermann (1.1.2)
43
44
  ruby2_keywords (~> 0.0.1)
44
- mustermann-contrib (1.1.1)
45
+ mustermann-contrib (1.1.2)
45
46
  hansi (~> 0.2.0)
46
- mustermann (= 1.1.1)
47
+ mustermann (= 1.1.2)
47
48
  parallel (1.22.1)
48
- parser (3.1.1.0)
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.3)
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.2.1)
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.27.0)
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.16.0, < 2.0)
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.16.0)
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.1.0)
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 serialized the response body to json if needed.
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" calls: `MyApi::Pets::Create.new.call(params, response)` If `MyApi::Pets::Create.new` accepts an argument, it will pass the rack `env`.
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
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- openapi_first (0.17.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.20)
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.2.1)
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
- return ->(params, res) { klass.new.call(params, res) } if klass.instance_method(:initialize).arity.zero?
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 content_type_for(status)
51
- content = response_for(status)['content']
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.content_type_for(res.status)
21
+ res[Rack::CONTENT_TYPE] ||= operation.content_types_for(res.status)&.first
22
22
  res.finish
23
23
  end
24
24
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenapiFirst
4
- VERSION = '0.17.0'
4
+ VERSION = '0.19.0'
5
5
  end
data/lib/openapi_first.rb CHANGED
@@ -20,7 +20,7 @@ module OpenapiFirst
20
20
  HANDLER = 'openapi_first.handler'
21
21
 
22
22
  def self.env
23
- ENV['RACK_ENV'] || ENV['HANAMI_ENV'] || ENV['RAILS_ENV']
23
+ ENV['RACK_ENV'] || ENV['HANAMI_ENV'] || ENV.fetch('RAILS_ENV', nil)
24
24
  end
25
25
 
26
26
  def self.load(spec_path, only: nil)
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.17.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-04-11 00:00:00.000000000 Z
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