openapi_first 0.17.0 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
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