openapi_first 0.8.0 → 0.9.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: 82bb84c8685503083fd1b5ef61e6839c706e2a2152c093af842fe96e9a0004cd
4
- data.tar.gz: 20165b2fcb4f10004cd6ee4cab55eeec912bcac6d8d86255cb08c2f2e9f0e8a6
3
+ metadata.gz: 50a431b59d4568cede6b8a110ada173691c698517231299795ee22fc8f54115a
4
+ data.tar.gz: be49aa45dd7b95ee0ec2149b4ec6476c78a42a0e46204c321e5350368bee2d54
5
5
  SHA512:
6
- metadata.gz: dd403e00cdd880573c10de5949db863afd3791eb3271ef26d227e4dffe9efa9775dbb84847acbc3fd79fbc1630be1dc6e71b0c6e7362a992f6350ab2fadf4b1f
7
- data.tar.gz: 9080c126f4a6083ed3e16bcb7f7fd5503b0efaa6633f40cfce2ce85afae4531f15c845ecb76e0138c9395626ec860a7bc9ac51df29c0d11fb2a4970583b5e86e
6
+ metadata.gz: b6b29dab24a951716e9fb73a7f852a4acd3de577cce82008cd329906ef77d73c4cff182face7adb1d36e9ecb9ea170d1655accb9cdc3bba682a818c3c81000b0
7
+ data.tar.gz: d0ad9c915cb4e637dce9ff4f0e6a8bc35cf705c684f69f38d9abbc8edada4b8aef0d2ba226cfae187f9d80da3a229e0f9493ac78bddb0045206ed816cbfe022e
@@ -1,5 +1,8 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.9.0
4
+ - Make request validation usable standalone
5
+
3
6
  ## 0.8.0
4
7
  - Add merged parameter and request body available to env at `env[OpenapiFirst::INBOX]` in request validation
5
8
  - Path and query parameters with `type: boolean` now get converted to `true`/`false`
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openapi_first (0.8.0)
4
+ openapi_first (0.9.0)
5
5
  hanami-router (~> 2.0.alpha2)
6
6
  hanami-utils (~> 2.0.alpha1)
7
7
  json_schemer (~> 0.2)
data/README.md CHANGED
@@ -35,27 +35,31 @@ Handler functions (`find_pet`) are called with two arguments:
35
35
  - `params` - Holds the parsed request body, filtered query params and path parameters
36
36
  - `res` - Holds a Rack::Response that you can modify if needed
37
37
  If you want to access to plain Rack env you can call `params.env`.
38
+
39
+ ## Rack middlewares
40
+ OpenapiFirst consists of these Rack middlewares:
38
41
 
39
- ### Handling only certain paths
42
+ - `OpenapiFirst::Router` finds the operation for the current request and finds a handler (if namespace option is given)
43
+ - `OpenapiFirst::RequestValidation` validates the request and returns 400 if it's invalid
44
+ - `OpenapiFirst::OperationResolver` calls the handler
40
45
 
41
- You can filter the URIs that should be handled by pass ing `only` to `OpenapiFirst.load`:
46
+ Instead of using `OpenapiFirst.app` you can use these middlwares by itself.
42
47
 
43
- ```ruby
44
- spec = OpenapiFirst.load './openapi/openapi.yaml', only: '/pets'.method(:==)
45
- run OpenapiFirst.app(spec, namespace: Pets)
46
- ```
47
-
48
- ### Usage as Rack middleware
48
+ ## Usage within your Rack webframework
49
+ If you just want to use the request validation part without any handlers you can use the rack middlewares standalone and don't need to pass a `namespace` option:
49
50
 
50
51
  ```ruby
51
- # Just like the above, except the last line
52
- # ...
53
- run OpenapiFirst.middleware('./openapi/openapi.yaml', namespace: Pets)
52
+ use OpenapiFirst::Router, spec: OpenapiFirst.load('./openapi/openapi.yaml')
53
+ use OpenapiFirst::RequestValidation
54
54
  ```
55
55
 
56
- When using the middleware, all requests that are not part of the API description will be passed to the next app.
56
+ ### Rack env variables
57
+ These variables will available in your rack env:
57
58
 
58
- ### Try it out
59
+ - `env[OpenapiFirst::OPERATION]` - Holds an Operation object that responsed about `operation_id` and `path`. This is useful for introspection.
60
+ - `env[OpenapiFirst::INBOX]`. Holds the (filtered) path and query parameters and the response body.
61
+
62
+ ## Try it out
59
63
 
60
64
  See [examples](examples).
61
65
 
@@ -147,6 +151,24 @@ validator = OpenapiFirst::ResponseValidator.new(spec)
147
151
  expect(validator.validate(last_request, last_response).errors).to be_empty
148
152
  ```
149
153
 
154
+ ## If your API description does not contain all endpoints
155
+
156
+ ```ruby
157
+ run OpenapiFirst.middleware('./openapi/openapi.yaml', namespace: Pets)
158
+ ```
159
+
160
+ Here all requests that are not part of the API description will be passed to the next app.
161
+
162
+ ## Handling only certain paths
163
+
164
+ You can filter the URIs that should be handled by passing `only` to `OpenapiFirst.load`:
165
+
166
+ ```ruby
167
+ spec = OpenapiFirst.load './openapi/openapi.yaml', only: '/pets'.method(:==)
168
+ run OpenapiFirst.app(spec, namespace: Pets)
169
+ ```
170
+
171
+
150
172
  ## Coverage
151
173
 
152
174
  (This is a bit experimental. Please try it out and give feedback.)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- openapi_first (0.8.0)
4
+ openapi_first (0.9.0)
5
5
  hanami-router (~> 2.0.alpha2)
6
6
  hanami-utils (~> 2.0.alpha1)
7
7
  json_schemer (~> 0.2)
@@ -2,11 +2,15 @@
2
2
 
3
3
  require 'openapi_first'
4
4
 
5
- module Example
6
- def self.find_thing(_params, _res)
7
- { hello: 'world' }
5
+ module Web
6
+ module Things
7
+ class Index
8
+ def call(_params, _response)
9
+ { hello: 'world' }
10
+ end
11
+ end
8
12
  end
9
13
  end
10
14
 
11
15
  oas_path = File.absolute_path('./openapi.yaml', __dir__)
12
- App = OpenapiFirst.app(oas_path, namespace: Example)
16
+ App = OpenapiFirst.app(oas_path, namespace: Web)
@@ -12,7 +12,7 @@ tags:
12
12
  paths:
13
13
  /:
14
14
  get:
15
- operationId: find_thing
15
+ operationId: things#index
16
16
  summary: Get metadata from the root of the API
17
17
  tags: ["Metadata"]
18
18
  responses:
@@ -10,7 +10,7 @@ module OpenapiFirst
10
10
 
11
11
  def initialize(app, options)
12
12
  @app = app
13
- @namespace = options.fetch(:namespace)
13
+ @namespace = options.fetch(:namespace, nil)
14
14
  @parent_app = options.fetch(:parent_app, nil)
15
15
  @router = build_router(options.fetch(:spec).operations)
16
16
  end
@@ -74,8 +74,8 @@ module OpenapiFirst
74
74
  warn "operationId is missing in '#{operation.method} #{operation.path}'. I am ignoring this operation." # rubocop:disable Layout/LineLength
75
75
  next
76
76
  end
77
- handler = find_handler(operation.operation_id)
78
- if handler.nil?
77
+ handler = @namespace && find_handler(operation.operation_id)
78
+ if @namespace && handler.nil?
79
79
  warn "#{self.class.name} cannot not find handler for '#{operation.operation_id}' (#{operation.method} #{operation.path}). This operation will be ignored." # rubocop:disable Layout/LineLength
80
80
  next
81
81
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenapiFirst
4
- VERSION = '0.8.0'
4
+ VERSION = '0.9.0'
5
5
  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.8.0
4
+ version: 0.9.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: 2020-04-20 00:00:00.000000000 Z
11
+ date: 2020-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hanami-router
@@ -176,7 +176,6 @@ files:
176
176
  - benchmarks/apps/hanami_router.ru
177
177
  - benchmarks/apps/openapi.yaml
178
178
  - benchmarks/apps/openapi_first.ru
179
- - benchmarks/apps/openapi_first_resolve_only.ru
180
179
  - benchmarks/apps/sinatra.ru
181
180
  - benchmarks/apps/syro.ru
182
181
  - benchmarks/benchmarks.rb
@@ -1,23 +0,0 @@
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
- spec = OpenapiFirst.load(File.absolute_path('./openapi.yaml', __dir__))
22
- use OpenapiFirst::Router, spec: spec, namespace: namespace
23
- run OpenapiFirst::OperationResolver.new