openapi_first 0.10.1 → 0.12.0.alpha2
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/.rubocop.yml +12 -0
- data/CHANGELOG.md +22 -0
- data/Gemfile.lock +15 -13
- data/README.md +126 -83
- data/benchmarks/Gemfile.lock +11 -11
- data/examples/app.rb +6 -1
- data/lib/openapi_first.rb +46 -5
- data/lib/openapi_first/app.rb +9 -11
- data/lib/openapi_first/definition.rb +3 -12
- data/lib/openapi_first/find_handler.rb +60 -0
- data/lib/openapi_first/operation.rb +23 -5
- data/lib/openapi_first/request_validation.rb +18 -8
- data/lib/openapi_first/responder.rb +46 -0
- data/lib/openapi_first/response_object.rb +21 -0
- data/lib/openapi_first/response_validation.rb +67 -0
- data/lib/openapi_first/response_validator.rb +17 -10
- data/lib/openapi_first/router.rb +35 -47
- data/lib/openapi_first/router_required.rb +13 -0
- data/lib/openapi_first/validation_format.rb +3 -1
- data/lib/openapi_first/version.rb +1 -1
- data/openapi_first.gemspec +7 -7
- metadata +11 -7
- data/lib/openapi_first/operation_resolver.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d0848ff82fa49a93053ec107ca28c419c1be8b9122301a8819742685e8b7995
|
4
|
+
data.tar.gz: 11cf9a3c60b619cd55d7f3f552a2c367553aa69ed047ddd101eff1b460ee4c53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5cabc3434dd9c4801b3f6ec030ec4ad5ef6905762a2643ef59a99f78057e6b108f90bf24696d29cab776dfa61a571be4973af7f62af07f5672f64996fb77086d
|
7
|
+
data.tar.gz: b7391c86d982be35d680e56f904261b8cfbd846a8206c2f339adc703248ad2476121fb8534a9562a20e081a2e5d5a8696231937affb23a72fe917a546a7e34c2
|
data/.rubocop.yml
CHANGED
@@ -8,10 +8,22 @@ Metrics/BlockLength:
|
|
8
8
|
Exclude:
|
9
9
|
- 'spec/**/*.rb'
|
10
10
|
- '*.gemspec'
|
11
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
12
|
+
Enabled: true
|
11
13
|
Layout/SpaceAroundMethodCallOperator:
|
12
14
|
Enabled: true
|
15
|
+
Lint/DeprecatedOpenSSLConstant:
|
16
|
+
Enabled: true
|
13
17
|
Lint/RaiseException:
|
14
18
|
Enabled: true
|
19
|
+
Lint/MixedRegexpCaptureTypes:
|
20
|
+
Enabled: true
|
21
|
+
Style/RedundantRegexpCharacterClass:
|
22
|
+
Enabled: true
|
23
|
+
Style/RedundantRegexpEscape:
|
24
|
+
Enabled: true
|
25
|
+
Style/SlicingWithRange:
|
26
|
+
Enabled: true
|
15
27
|
Lint/StructNewOverride:
|
16
28
|
Enabled: true
|
17
29
|
Style/HashEachMethods:
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,27 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## Unreleased
|
4
|
+
- Add `raise_error` option to OpenapiFirst.app (false by default)
|
5
|
+
- Add ResponseValidation to OpenapiFirst.app if raise_error option is true
|
6
|
+
- Rename `raise` option to `raise_error`
|
7
|
+
- Add `raise_error` option to RequestValidation middleware
|
8
|
+
- Raise error if handler could not be found by Responder
|
9
|
+
- Add `Operation#name` that returns a human readable name for an operation
|
10
|
+
|
11
|
+
## 0.11.0
|
12
|
+
- Raise error if you forgot to add the Router middleware
|
13
|
+
- Make OpenapiFirst.app raise an error in test env when request path is not specified
|
14
|
+
- Rename OperationResolver to Responder
|
15
|
+
- Add ResponseValidation middleware that validates the response body
|
16
|
+
- Add `raise` option to Router middleware to raise an error if request could not be found in the API description similar to committee's raise option.
|
17
|
+
- Move namespace option from Router to OperationResolver
|
18
|
+
|
19
|
+
## 0.10.2
|
20
|
+
- Return 400 if request body has invalid JSON ([issue](https://github.com/ahx/openapi_first/issues/73)) thanks Thomas Frütel
|
21
|
+
|
22
|
+
## 0.10.1
|
23
|
+
- Fix duplicated key in `required` when generating JSON schema for `some[thing]` parameters
|
24
|
+
|
3
25
|
## 0.10.0
|
4
26
|
- Add support for query parameters named `"some[thing]"` ([issue](https://github.com/ahx/openapi_first/issues/40))
|
5
27
|
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
openapi_first (0.
|
4
|
+
openapi_first (0.12.0.alpha2)
|
5
5
|
deep_merge (>= 1.2.1)
|
6
|
-
hanami-router (~> 2.0.
|
6
|
+
hanami-router (~> 2.0.alpha3)
|
7
7
|
hanami-utils (~> 2.0.alpha1)
|
8
8
|
json_schemer (~> 0.2)
|
9
9
|
multi_json (~> 1.14)
|
@@ -13,7 +13,7 @@ PATH
|
|
13
13
|
GEM
|
14
14
|
remote: https://rubygems.org/
|
15
15
|
specs:
|
16
|
-
activesupport (6.0.3)
|
16
|
+
activesupport (6.0.3.1)
|
17
17
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
18
18
|
i18n (>= 0.7, < 2)
|
19
19
|
minitest (~> 5.1)
|
@@ -23,14 +23,14 @@ GEM
|
|
23
23
|
public_suffix (>= 2.0.2, < 5.0)
|
24
24
|
ast (2.4.0)
|
25
25
|
builder (3.2.4)
|
26
|
-
coderay (1.1.
|
26
|
+
coderay (1.1.3)
|
27
27
|
concurrent-ruby (1.1.6)
|
28
28
|
deep_merge (1.2.1)
|
29
29
|
diff-lcs (1.3)
|
30
30
|
ecma-re-validator (0.2.1)
|
31
31
|
regexp_parser (~> 1.2)
|
32
32
|
hana (1.3.6)
|
33
|
-
hanami-router (2.0.0.
|
33
|
+
hanami-router (2.0.0.alpha3)
|
34
34
|
mustermann (~> 1.0)
|
35
35
|
mustermann-contrib (~> 1.0)
|
36
36
|
rack (~> 2.0)
|
@@ -39,9 +39,8 @@ GEM
|
|
39
39
|
transproc (~> 1.0)
|
40
40
|
hansi (0.2.0)
|
41
41
|
hash-deep-merge (0.1.1)
|
42
|
-
i18n (1.8.
|
42
|
+
i18n (1.8.3)
|
43
43
|
concurrent-ruby (~> 1.0)
|
44
|
-
jaro_winkler (1.5.4)
|
45
44
|
json_schemer (0.2.11)
|
46
45
|
ecma-re-validator (~> 0.2)
|
47
46
|
hana (~> 1.3)
|
@@ -49,7 +48,7 @@ GEM
|
|
49
48
|
uri_template (~> 0.7)
|
50
49
|
method_source (1.0.0)
|
51
50
|
mini_portile2 (2.4.0)
|
52
|
-
minitest (5.14.
|
51
|
+
minitest (5.14.1)
|
53
52
|
multi_json (1.14.1)
|
54
53
|
mustermann (1.1.1)
|
55
54
|
ruby2_keywords (~> 0.0.1)
|
@@ -67,12 +66,12 @@ GEM
|
|
67
66
|
mustermann-contrib (~> 1.1.1)
|
68
67
|
nokogiri
|
69
68
|
parallel (1.19.1)
|
70
|
-
parser (2.7.1.
|
69
|
+
parser (2.7.1.3)
|
71
70
|
ast (~> 2.4.0)
|
72
71
|
pry (0.13.1)
|
73
72
|
coderay (~> 1.1)
|
74
73
|
method_source (~> 1.0)
|
75
|
-
public_suffix (4.0.
|
74
|
+
public_suffix (4.0.5)
|
76
75
|
rack (2.2.2)
|
77
76
|
rack-test (1.1.0)
|
78
77
|
rack (>= 1.0, < 3)
|
@@ -86,21 +85,24 @@ GEM
|
|
86
85
|
rspec-mocks (~> 3.9.0)
|
87
86
|
rspec-core (3.9.2)
|
88
87
|
rspec-support (~> 3.9.3)
|
89
|
-
rspec-expectations (3.9.
|
88
|
+
rspec-expectations (3.9.2)
|
90
89
|
diff-lcs (>= 1.2.0, < 2.0)
|
91
90
|
rspec-support (~> 3.9.0)
|
92
91
|
rspec-mocks (3.9.1)
|
93
92
|
diff-lcs (>= 1.2.0, < 2.0)
|
94
93
|
rspec-support (~> 3.9.0)
|
95
94
|
rspec-support (3.9.3)
|
96
|
-
rubocop (0.
|
97
|
-
jaro_winkler (~> 1.5.1)
|
95
|
+
rubocop (0.85.0)
|
98
96
|
parallel (~> 1.10)
|
99
97
|
parser (>= 2.7.0.1)
|
100
98
|
rainbow (>= 2.2.2, < 4.0)
|
99
|
+
regexp_parser (>= 1.7)
|
101
100
|
rexml
|
101
|
+
rubocop-ast (>= 0.0.3)
|
102
102
|
ruby-progressbar (~> 1.7)
|
103
103
|
unicode-display_width (>= 1.4.0, < 2.0)
|
104
|
+
rubocop-ast (0.0.3)
|
105
|
+
parser (>= 2.7.0.1)
|
104
106
|
ruby-progressbar (1.10.1)
|
105
107
|
ruby2_keywords (0.0.2)
|
106
108
|
thread_safe (0.3.6)
|
data/README.md
CHANGED
@@ -1,32 +1,143 @@
|
|
1
1
|
# OpenapiFirst
|
2
2
|
|
3
|
+
[](https://gitter.im/openapi_first/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
4
|
+
|
3
5
|
OpenapiFirst helps to implement HTTP APIs based on an [OpenApi](https://www.openapis.org/) API description. The idea is that you create an API description first, then add code that returns data and implements your business logic and be done.
|
4
6
|
|
5
|
-
Start with writing an OpenAPI file that describes the API, which you are about to
|
7
|
+
Start with writing an OpenAPI file that describes the API, which you are about to implement. Use a [validator](https://github.com/stoplightio/spectral/) to make sure the file is valid.
|
8
|
+
|
9
|
+
You can use OpenapiFirst via its [Rack middlewares](#rack-middlewares) or in [standalone mode](#standalone-usage).
|
10
|
+
|
11
|
+
## Alternatives
|
12
|
+
|
13
|
+
This gem is inspired by [committee](https://github.com/interagent/committee) (Ruby) and [connexion](https://github.com/zalando/connexion) (Python).
|
14
|
+
|
15
|
+
Here's a [comparison between committee and openapi_first](https://gist.github.com/ahx/1538c31f0652f459861713b5259e366a).
|
6
16
|
|
7
17
|
## Rack middlewares
|
8
18
|
OpenapiFirst consists of these Rack middlewares:
|
9
19
|
|
10
|
-
- `OpenapiFirst::Router`
|
11
|
-
- `OpenapiFirst::RequestValidation`
|
12
|
-
- `OpenapiFirst::
|
20
|
+
- [`OpenapiFirst::Router`](#OpenapiFirst::Router) – Finds the OpenAPI operation for the current request or returns 404 if no operation was found. This can be customized.
|
21
|
+
- [`OpenapiFirst::RequestValidation`](#OpenapiFirst::RequestValidation) – Validates the request against the API description and returns 400 if the request is invalid.
|
22
|
+
- [`OpenapiFirst::Responder`](#OpenapiFirst::Responder) calls the [handler](#handlers) found for the operation.
|
23
|
+
- [`OpenapiFirst::ResponseValidation`](#OpenapiFirst::ResponseValidation) Validates the response and raises an exception if the response body is invalid.
|
13
24
|
|
14
|
-
##
|
15
|
-
|
25
|
+
## OpenapiFirst::Router
|
26
|
+
You always have to add this middleware first in order to make the other middlewares work.
|
16
27
|
|
17
28
|
```ruby
|
18
29
|
use OpenapiFirst::Router, spec: OpenapiFirst.load('./openapi/openapi.yaml')
|
30
|
+
```
|
31
|
+
|
32
|
+
This middleware adds `env[OpenapiFirst::OPERATION]` which holds an Operation object that responds to `operation_id` and `path`.
|
33
|
+
|
34
|
+
Options and their defaults:
|
35
|
+
|
36
|
+
| Name | Possible values | Description | Default
|
37
|
+
|:---|---|---|---|
|
38
|
+
|`spec:`| | The spec loaded via `OpenapiFirst.load` ||
|
39
|
+
| `not_found:` |`nil`, `:continue`, `Proc`| Specifies what to do if the path was not found in the API description. `nil` (default) returns a 404 response. `:continue` does nothing an calls the next app. `Proc` (or something that responds to `call`) to customize the response. | `nil` (return 404)
|
40
|
+
| `raise_error:` |`false`, `true` | If set to true the middleware raises `OpenapiFirst::NotFoundError` when a path or method was not found in the API description. This is useful during testing to spot an incomplete API description. | `false` (don't raise an exception)
|
41
|
+
|
42
|
+
## OpenapiFirst::RequestValidation
|
43
|
+
|
44
|
+
This middleware returns a 400 status code with a body that describes the error if the request is not valid.
|
45
|
+
|
46
|
+
```ruby
|
19
47
|
use OpenapiFirst::RequestValidation
|
20
48
|
```
|
21
49
|
|
22
|
-
### Rack env variables
|
23
|
-
These variables will available in your rack env:
|
24
50
|
|
25
|
-
|
26
|
-
|
51
|
+
Options and their defaults:
|
52
|
+
|
53
|
+
| Name | Possible values | Description | Default
|
54
|
+
|:---|---|---|---|
|
55
|
+
| `raise_error:` |`false`, `true` | If set to true the middleware raises `OpenapiFirst::RequestInvalidError` instead of returning 4xx. | `false` (don't raise an exception)
|
56
|
+
|
57
|
+
The error responses conform with [JSON:API](https://jsonapi.org).
|
58
|
+
|
59
|
+
Here's an example response body for a missing query parameter "search":
|
60
|
+
|
61
|
+
```json
|
62
|
+
http-status: 400
|
63
|
+
content-type: "application/vnd.api+json"
|
64
|
+
|
65
|
+
{
|
66
|
+
"errors": [
|
67
|
+
{
|
68
|
+
"title": "is missing",
|
69
|
+
"source": {
|
70
|
+
"parameter": "search"
|
71
|
+
}
|
72
|
+
}
|
73
|
+
]
|
74
|
+
}
|
75
|
+
```
|
76
|
+
|
77
|
+
This middleware adds `env[OpenapiFirst::INBOX]` which holds the (filtered) path and query parameters and the parsed request body.
|
78
|
+
|
79
|
+
### Parameter validation
|
80
|
+
|
81
|
+
The middleware filteres all top-level query parameters and paths parameters and tries to convert numeric values. Meaning, if you have an `:something_id` path with `type: integer`, it will try convert the value to an integer.
|
82
|
+
Note that is currently does not convert date, date-time or time formats and that conversion is currently done only for path and query parameters, but not for the request body. It just works with a parameter with `name: filter[age]`.
|
83
|
+
|
84
|
+
If you want to forbid _nested_ query parameters you will need to use [`additionalProperties: false`](https://json-schema.org/understanding-json-schema/reference/object.html#properties) in your query parameter JSON schema.
|
85
|
+
|
86
|
+
_OpenapiFirst always treats query parameters like [`style: deepObject`](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#style-values), **but** it just works with nested objects (`filter[foo][bar]=baz`) (see [this discussion](https://github.com/OAI/OpenAPI-Specification/issues/1706))._
|
87
|
+
|
88
|
+
### Request body validation
|
89
|
+
|
90
|
+
The middleware will return a status `415` if the requests content type does not match or `400` if the request body is invalid.
|
91
|
+
This will also add the parsed request body to `env[OpenapiFirst::REQUEST_BODY]`.
|
92
|
+
|
93
|
+
### Header, Cookie, Path parameter validation
|
94
|
+
|
95
|
+
tbd.
|
96
|
+
|
97
|
+
## OpenapiFirst::Responder
|
98
|
+
|
99
|
+
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. Responder also adds a content-type to the response.
|
100
|
+
|
101
|
+
Currently there are no customization options for this part. Please [share your ideas](#contributing) on how to best meet your needs and preferred style.
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
run OpenapiFirst::Responder, spec: OpenapiFirst.load('./openapi/openapi.yaml')
|
105
|
+
```
|
106
|
+
|
107
|
+
| Name | Description
|
108
|
+
|:---|---|
|
109
|
+
|`spec:`| The spec loaded via `OpenapiFirst.load` |
|
110
|
+
| `namespace:` | A class or module where to find the handler method. |
|
111
|
+
|
112
|
+
It works like this:
|
113
|
+
|
114
|
+
- An operationId "create_pet" or "createPet" or "create pet" calls `MyApi.create_pet(params, response)`
|
115
|
+
- "some_things.create" calls: `MyApi::SomeThings.create(params, response)`
|
116
|
+
- "pets#create" calls: `MyApi::Pets::Create.new.call(params, response)` If `MyApi::Pets::Create.new` accepts an argument, it will pass the rack `env`.
|
117
|
+
|
118
|
+
### Handlers
|
119
|
+
|
120
|
+
These handler methods are called with two arguments:
|
121
|
+
|
122
|
+
- `params` - Holds the parsed request body, filtered query params and path parameters (same as `env[OpenapiFirst::INBOX]`)
|
123
|
+
- `res` - Holds a Rack::Response that you can modify if needed
|
124
|
+
|
125
|
+
You can call `params.env` to access the Rack env (just like in [Hanami actions](https://guides.hanamirb.org/actions/parameters/))
|
126
|
+
|
127
|
+
There are two ways to set the response body:
|
128
|
+
|
129
|
+
- Calling `res.write "things"` (see [Rack::Response](https://www.rubydoc.info/github/rack/rack/Rack/Response))
|
130
|
+
- Returning a value which will get converted to JSON
|
131
|
+
|
132
|
+
## OpenapiFirst::ResponseValidation
|
133
|
+
This middleware is especially useful when testing. It *always* raises an error if the response is not valid.
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
use OpenapiFirst::ResponseValidation if ENV['RACK_ENV'] == 'test'
|
137
|
+
```
|
27
138
|
|
28
139
|
## Standalone usage
|
29
|
-
|
140
|
+
Instead of composing these middlewares yourself you can use `OpenapiFirst.app`.
|
30
141
|
|
31
142
|
```ruby
|
32
143
|
module Pets
|
@@ -55,29 +166,7 @@ Handler functions (`find_pet`) are called with two arguments:
|
|
55
166
|
- `res` - Holds a Rack::Response that you can modify if needed
|
56
167
|
If you want to access to plain Rack env you can call `params.env`.
|
57
168
|
|
58
|
-
|
59
|
-
|
60
|
-
OpenapiFirst 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 via the `OperationResolver` middleware.
|
61
|
-
|
62
|
-
It works like this:
|
63
|
-
|
64
|
-
- "create_pet" or "createPet" or "create pet" calls `MyApi.create_pet(params, response)`
|
65
|
-
- "some_things.create" calls: `MyApi::SomeThings.create(params, response)`
|
66
|
-
- "pets#create" calls: `MyApi::Pets::Create.new.call(params, response)` If `MyApi::Pets::Create.new` accepts an argument, it will pass the rack `env`.
|
67
|
-
|
68
|
-
These handler methods are called with two arguments:
|
69
|
-
|
70
|
-
- `params` - Holds the parsed request body, filtered query params and path parameters
|
71
|
-
- `res` - Holds a Rack::Response that you can modify if needed
|
72
|
-
|
73
|
-
You can call `params.env` to access the Rack env (just like in [Hanami actions](https://guides.hanamirb.org/actions/parameters/))
|
74
|
-
|
75
|
-
There are two ways to set the response body:
|
76
|
-
|
77
|
-
- Calling `res.write "things"` (see [Rack::Response](https://www.rubydoc.info/github/rack/rack/Rack/Response))
|
78
|
-
- Returning a value from the function (see example above) (this will always converted to JSON)
|
79
|
-
|
80
|
-
### If your API description does not contain all endpoints
|
169
|
+
## If your API description does not contain all endpoints
|
81
170
|
|
82
171
|
```ruby
|
83
172
|
run OpenapiFirst.middleware('./openapi/openapi.yaml', namespace: Pets)
|
@@ -85,7 +174,7 @@ run OpenapiFirst.middleware('./openapi/openapi.yaml', namespace: Pets)
|
|
85
174
|
|
86
175
|
Here all requests that are not part of the API description will be passed to the next app.
|
87
176
|
|
88
|
-
|
177
|
+
## Try it out
|
89
178
|
|
90
179
|
See [examples](examples).
|
91
180
|
|
@@ -99,49 +188,7 @@ gem 'openapi_first'
|
|
99
188
|
|
100
189
|
OpenapiFirst uses [`multi_json`](https://rubygems.org/gems/multi_json).
|
101
190
|
|
102
|
-
##
|
103
|
-
|
104
|
-
If the request is not valid, these middlewares return a 400 status code with a body that describes the error.
|
105
|
-
|
106
|
-
The error responses conform with [JSON:API](https://jsonapi.org).
|
107
|
-
|
108
|
-
Here's an example response body for a missing query parameter "search":
|
109
|
-
|
110
|
-
```json
|
111
|
-
http-status: 400
|
112
|
-
content-type: "application/vnd.api+json"
|
113
|
-
|
114
|
-
{
|
115
|
-
"errors": [
|
116
|
-
{
|
117
|
-
"title": "is missing",
|
118
|
-
"source": {
|
119
|
-
"parameter": "search"
|
120
|
-
}
|
121
|
-
}
|
122
|
-
]
|
123
|
-
}
|
124
|
-
```
|
125
|
-
|
126
|
-
### Parameter validation
|
127
|
-
|
128
|
-
The middleware filteres all top-level query parameters and paths parameters and tries to convert numeric values. Meaning, if you have an `:something_id` path with `type: integer`, it will try convert the value to an integer.
|
129
|
-
Note that is currently does not convert date, date-time or time formats and that conversion is currently on done for path and query parameters, but not for request bodies.
|
130
|
-
|
131
|
-
If you want to forbid _nested_ query parameters you will need to use [`additionalProperties: false`](https://json-schema.org/understanding-json-schema/reference/object.html#properties) in your query parameter JSON schema.
|
132
|
-
|
133
|
-
_OpenapiFirst always treats query parameters like [`style: deepObject`](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#style-values), **but** it just works with nested objects (`filter[foo][bar]=baz`) (see [this discussion](https://github.com/OAI/OpenAPI-Specification/issues/1706))._
|
134
|
-
|
135
|
-
### Request body validation
|
136
|
-
|
137
|
-
The middleware will return a `415` if the requests content type does not match or `400` if the request body is invalid.
|
138
|
-
This will add the parsed request body to `env[OpenapiFirst::REQUEST_BODY]`.
|
139
|
-
|
140
|
-
### Header, Cookie, Path parameter validation
|
141
|
-
|
142
|
-
tbd.
|
143
|
-
|
144
|
-
## Response validation
|
191
|
+
## Manual response validation
|
145
192
|
|
146
193
|
Response validation is useful to make sure your app responds as described in your API description. You usually do this in your tests using [rack-test](https://github.com/rack-test/rack-test).
|
147
194
|
|
@@ -202,10 +249,6 @@ end
|
|
202
249
|
|
203
250
|
Out of scope. Use [Prism](https://github.com/stoplightio/prism) or [fakeit](https://github.com/JustinFeng/fakeit).
|
204
251
|
|
205
|
-
## Alternatives
|
206
|
-
|
207
|
-
This gem is inspired by [committee](https://github.com/interagent/committee), which has much more features like response stubs or support for Hyper-Schema or OpenAPI 2.
|
208
|
-
|
209
252
|
## Development
|
210
253
|
|
211
254
|
Run `bin/setup` to install dependencies.
|
@@ -224,6 +267,6 @@ bundle exec ruby benchmarks.rb
|
|
224
267
|
|
225
268
|
## Contributing
|
226
269
|
|
227
|
-
If you have a question or an idea or found a bug don't hesitate to [create an issue on GitHub](https://github.com/ahx/openapi_first/issues).
|
270
|
+
If you have a question or an idea or found a bug don't hesitate to [create an issue on GitHub](https://github.com/ahx/openapi_first/issues) or [reach out via chat](https://gitter.im/openapi_first/community).
|
228
271
|
|
229
272
|
Pull requests are very welcome as well, of course. Feel free to create a "draft" pull request early on, even if your change is still work in progress. 🤗
|
data/benchmarks/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
openapi_first (0.
|
4
|
+
openapi_first (0.12.0.alpha2)
|
5
5
|
deep_merge (>= 1.2.1)
|
6
|
-
hanami-router (~> 2.0.
|
6
|
+
hanami-router (~> 2.0.alpha3)
|
7
7
|
hanami-utils (~> 2.0.alpha1)
|
8
8
|
json_schemer (~> 0.2)
|
9
9
|
multi_json (~> 1.14)
|
@@ -13,7 +13,7 @@ PATH
|
|
13
13
|
GEM
|
14
14
|
remote: https://rubygems.org/
|
15
15
|
specs:
|
16
|
-
activesupport (6.0.3)
|
16
|
+
activesupport (6.0.3.1)
|
17
17
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
18
18
|
i18n (>= 0.7, < 2)
|
19
19
|
minitest (~> 5.1)
|
@@ -25,9 +25,9 @@ GEM
|
|
25
25
|
benchmark-memory (0.1.2)
|
26
26
|
memory_profiler (~> 0.9)
|
27
27
|
builder (3.2.4)
|
28
|
-
committee (
|
28
|
+
committee (4.0.0)
|
29
29
|
json_schema (~> 0.14, >= 0.14.3)
|
30
|
-
openapi_parser (>= 0.
|
30
|
+
openapi_parser (>= 0.11.1)
|
31
31
|
rack (>= 1.5)
|
32
32
|
concurrent-ruby (1.1.6)
|
33
33
|
deep_merge (1.2.1)
|
@@ -55,7 +55,7 @@ GEM
|
|
55
55
|
dry-logic (~> 1.0, >= 1.0.2)
|
56
56
|
ecma-re-validator (0.2.1)
|
57
57
|
regexp_parser (~> 1.2)
|
58
|
-
grape (1.3.
|
58
|
+
grape (1.3.3)
|
59
59
|
activesupport
|
60
60
|
builder
|
61
61
|
dry-types (>= 1.1)
|
@@ -63,7 +63,7 @@ GEM
|
|
63
63
|
rack (>= 1.3.0)
|
64
64
|
rack-accept
|
65
65
|
hana (1.3.6)
|
66
|
-
hanami-router (2.0.0.
|
66
|
+
hanami-router (2.0.0.alpha3)
|
67
67
|
mustermann (~> 1.0)
|
68
68
|
mustermann-contrib (~> 1.0)
|
69
69
|
rack (~> 2.0)
|
@@ -82,7 +82,7 @@ GEM
|
|
82
82
|
uri_template (~> 0.7)
|
83
83
|
memory_profiler (0.9.14)
|
84
84
|
mini_portile2 (2.4.0)
|
85
|
-
minitest (5.14.
|
85
|
+
minitest (5.14.1)
|
86
86
|
multi_json (1.14.1)
|
87
87
|
mustermann (1.1.1)
|
88
88
|
ruby2_keywords (~> 0.0.1)
|
@@ -101,14 +101,14 @@ GEM
|
|
101
101
|
hash-deep-merge
|
102
102
|
mustermann-contrib (~> 1.1.1)
|
103
103
|
nokogiri
|
104
|
-
openapi_parser (0.
|
105
|
-
public_suffix (4.0.
|
104
|
+
openapi_parser (0.11.2)
|
105
|
+
public_suffix (4.0.5)
|
106
106
|
rack (2.2.2)
|
107
107
|
rack-accept (0.4.5)
|
108
108
|
rack (>= 0.4)
|
109
109
|
rack-protection (2.0.8.1)
|
110
110
|
rack
|
111
|
-
regexp_parser (1.7.
|
111
|
+
regexp_parser (1.7.1)
|
112
112
|
ruby2_keywords (0.0.2)
|
113
113
|
seg (1.2.0)
|
114
114
|
sinatra (2.0.8.1)
|