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 +4 -4
- data/CHANGELOG.md +3 -0
- data/Gemfile.lock +1 -1
- data/README.md +35 -13
- data/benchmarks/Gemfile.lock +1 -1
- data/examples/app.rb +8 -4
- data/examples/openapi.yaml +1 -1
- data/lib/openapi_first/router.rb +3 -3
- data/lib/openapi_first/version.rb +1 -1
- metadata +2 -3
- data/benchmarks/apps/openapi_first_resolve_only.ru +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50a431b59d4568cede6b8a110ada173691c698517231299795ee22fc8f54115a
|
4
|
+
data.tar.gz: be49aa45dd7b95ee0ec2149b4ec6476c78a42a0e46204c321e5350368bee2d54
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6b29dab24a951716e9fb73a7f852a4acd3de577cce82008cd329906ef77d73c4cff182face7adb1d36e9ecb9ea170d1655accb9cdc3bba682a818c3c81000b0
|
7
|
+
data.tar.gz: d0ad9c915cb4e637dce9ff4f0e6a8bc35cf705c684f69f38d9abbc8edada4b8aef0d2ba226cfae187f9d80da3a229e0f9493ac78bddb0045206ed816cbfe022e
|
data/CHANGELOG.md
CHANGED
@@ -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`
|
data/Gemfile.lock
CHANGED
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
|
-
|
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
|
-
|
46
|
+
Instead of using `OpenapiFirst.app` you can use these middlwares by itself.
|
42
47
|
|
43
|
-
|
44
|
-
|
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
|
-
|
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
|
-
|
56
|
+
### Rack env variables
|
57
|
+
These variables will available in your rack env:
|
57
58
|
|
58
|
-
|
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.)
|
data/benchmarks/Gemfile.lock
CHANGED
data/examples/app.rb
CHANGED
@@ -2,11 +2,15 @@
|
|
2
2
|
|
3
3
|
require 'openapi_first'
|
4
4
|
|
5
|
-
module
|
6
|
-
|
7
|
-
|
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:
|
16
|
+
App = OpenapiFirst.app(oas_path, namespace: Web)
|
data/examples/openapi.yaml
CHANGED
data/lib/openapi_first/router.rb
CHANGED
@@ -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
|
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.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-
|
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
|