openapi_first 2.0.3 → 2.1.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 +10 -0
- data/lib/openapi_first/definition.rb +20 -2
- data/lib/openapi_first/errors.rb +11 -9
- data/lib/openapi_first/middlewares/response_validation.rb +0 -11
- data/lib/openapi_first/validated_request.rb +24 -16
- data/lib/openapi_first/validated_response.rb +18 -3
- data/lib/openapi_first/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c1cc903f3a064f2f386503959e1b437729ab8a668ffbf0dd5aac19c38b4faf4
|
4
|
+
data.tar.gz: 0ee337872917f9009c9e9b9d57da4382e7b34248cf7df51a2926b3c589bc2f46
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 30636bed981564cfe21696a46eb92d51ccb7680531b754dbfa37a6f52e37420f4e9611437e93ee54aada8eb6062db92ffd7fbce32eb1c76e8d856c5777b64444
|
7
|
+
data.tar.gz: 769c0821eca57bf60d8554ffd231b042511f57627f55c6083f2a9d054b35d08f0451d20f2411eaae035d7b3a591a046c57d732bf086143ac3d16162bf25b7c69
|
data/CHANGELOG.md
CHANGED
@@ -2,8 +2,18 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## 2.1.0
|
6
|
+
|
7
|
+
- Added `OpenapiFirst::Definition#[]` to access the raw Hash representation of the OAS document. Example: `api['components'].fetch('schemas', 'Stations')`
|
8
|
+
|
9
|
+
## 2.0.4
|
10
|
+
|
11
|
+
- Fix issue with parsing reponse body when using Rails https://github.com/ahx/openapi_first/issues/281
|
12
|
+
|
5
13
|
## 2.0.3
|
6
14
|
|
15
|
+
- Fix `OpenapiFirst::Test.register` https://github.com/ahx/openapi_first/issues/276
|
16
|
+
|
7
17
|
- Request validation middleware now accepts `error_response: false` do disable rendering a response. This is useful if you just want to collect metrics (via hooks) during a migration phase.
|
8
18
|
|
9
19
|
## 2.0.2
|
@@ -5,12 +5,22 @@ require_relative 'router'
|
|
5
5
|
require_relative 'request'
|
6
6
|
require_relative 'response'
|
7
7
|
require_relative 'builder'
|
8
|
+
require 'forwardable'
|
8
9
|
|
9
10
|
module OpenapiFirst
|
10
11
|
# Represents an OpenAPI API Description document
|
11
12
|
# This is returned by OpenapiFirst.load.
|
12
13
|
class Definition
|
13
|
-
|
14
|
+
extend Forwardable
|
15
|
+
|
16
|
+
# @return [String,nil]
|
17
|
+
attr_reader :filepath
|
18
|
+
# @return [Configuration]
|
19
|
+
attr_reader :config
|
20
|
+
# @return [Enumerable[String]]
|
21
|
+
attr_reader :paths
|
22
|
+
# @return [Router]
|
23
|
+
attr_reader :router
|
14
24
|
|
15
25
|
# @param resolved [Hash] The resolved OpenAPI document.
|
16
26
|
# @param filepath [String] The file path of the OpenAPI document.
|
@@ -20,15 +30,23 @@ module OpenapiFirst
|
|
20
30
|
yield @config if block_given?
|
21
31
|
@config.freeze
|
22
32
|
@router = Builder.build_router(resolved, @config)
|
33
|
+
@resolved = resolved
|
23
34
|
@paths = resolved['paths'].keys # TODO: Move into builder as well
|
24
35
|
end
|
25
36
|
|
37
|
+
# Gives access to the raw resolved Hash. Like `mydefinition['components'].dig('schemas', 'Stations')`
|
38
|
+
# @!method [](key)
|
39
|
+
# @return [Hash]
|
40
|
+
def_delegators :@resolved, :[]
|
41
|
+
|
42
|
+
# Returns an Enumerable of available Routes for this API description.
|
43
|
+
# @return [Enumerable[Router::Route]]
|
26
44
|
def routes
|
27
45
|
@router.routes
|
28
46
|
end
|
29
47
|
|
30
48
|
# Validates the request against the API description.
|
31
|
-
# @param [Rack::Request]
|
49
|
+
# @param [Rack::Request] request The Rack request object.
|
32
50
|
# @param [Boolean] raise_error Whether to raise an error if validation fails.
|
33
51
|
# @return [ValidatedRequest] The validated request object.
|
34
52
|
def validate_request(request, raise_error: false)
|
data/lib/openapi_first/errors.rb
CHANGED
@@ -1,38 +1,40 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module OpenapiFirst
|
4
|
-
#
|
4
|
+
# Base class for all errors
|
5
5
|
class Error < StandardError; end
|
6
|
-
|
6
|
+
|
7
|
+
# Raised if YAML/JSON file was not found
|
7
8
|
class FileNotFoundError < Error; end
|
8
|
-
|
9
|
+
|
10
|
+
# Raised if response body could not be parsed
|
9
11
|
class ParseError < Error; end
|
10
12
|
|
11
|
-
#
|
13
|
+
# Raised during request validation if request was invalid
|
12
14
|
class RequestInvalidError < Error
|
13
15
|
def initialize(message, validated_request)
|
14
16
|
super(message)
|
15
17
|
@request = validated_request
|
16
18
|
end
|
17
19
|
|
18
|
-
# @
|
20
|
+
# @return [ValidatedRequest] The validated request
|
19
21
|
attr_reader :request
|
20
22
|
end
|
21
23
|
|
22
|
-
#
|
24
|
+
# Raised during request validation if request was not defined in the API description
|
23
25
|
class NotFoundError < RequestInvalidError; end
|
24
26
|
|
25
|
-
#
|
27
|
+
# Raised during response validation if request was invalid
|
26
28
|
class ResponseInvalidError < Error
|
27
29
|
def initialize(message, validated_response)
|
28
30
|
super(message)
|
29
31
|
@response = validated_response
|
30
32
|
end
|
31
33
|
|
32
|
-
# @
|
34
|
+
# @return [ValidatedResponse] The validated response
|
33
35
|
attr_reader :response
|
34
36
|
end
|
35
37
|
|
36
|
-
#
|
38
|
+
# Raised during request validation if response was not defined in the API description
|
37
39
|
class ResponseNotFoundError < ResponseInvalidError; end
|
38
40
|
end
|
@@ -25,20 +25,9 @@ module OpenapiFirst
|
|
25
25
|
|
26
26
|
def call(env)
|
27
27
|
status, headers, body = @app.call(env)
|
28
|
-
body = read_body(body)
|
29
28
|
@definition.validate_response(Rack::Request.new(env), Rack::Response[status, headers, body], raise_error: @raise)
|
30
29
|
[status, headers, body]
|
31
30
|
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def read_body(body)
|
36
|
-
return body.to_ary if body.respond_to?(:to_ary)
|
37
|
-
|
38
|
-
result = []
|
39
|
-
body.each { |part| result << part }
|
40
|
-
result
|
41
|
-
end
|
42
31
|
end
|
43
32
|
end
|
44
33
|
end
|
@@ -15,46 +15,53 @@ module OpenapiFirst
|
|
15
15
|
@request_definition = request_definition
|
16
16
|
end
|
17
17
|
|
18
|
-
#
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
# A Failure object if the request is invalid
|
19
|
+
# @return [Failure, nil]
|
20
|
+
attr_reader :error
|
21
|
+
|
22
|
+
# The request definition if this request is defined in the API description
|
23
|
+
# @return [Request, nil]
|
24
|
+
attr_reader :request_definition
|
23
25
|
|
24
|
-
# Openapi 3 specific
|
25
|
-
# @!method operation
|
26
|
-
# @return [Hash] The OpenAPI 3 operation object
|
27
26
|
# @!method operation_id
|
28
|
-
#
|
29
|
-
|
27
|
+
# @return [String, nil] The OpenAPI 3 operationId
|
28
|
+
def_delegator :request_definition, :operation_id
|
29
|
+
|
30
|
+
# @!method operation
|
31
|
+
# @return [Hash] The raw OpenAPI 3 operation object
|
32
|
+
def_delegator :request_definition, :operation
|
30
33
|
|
31
34
|
# Parsed path parameters
|
32
|
-
#
|
35
|
+
# @return [Hash<String, anything>]
|
33
36
|
def parsed_path_parameters
|
34
|
-
parsed_values[:path]
|
37
|
+
@parsed_values[:path]
|
35
38
|
end
|
36
39
|
|
37
40
|
# Parsed query parameters. This only returns the query parameters that are defined in the OpenAPI spec.
|
41
|
+
# @return [Hash<String, anything>]
|
38
42
|
def parsed_query
|
39
|
-
parsed_values[:query]
|
43
|
+
@parsed_values[:query]
|
40
44
|
end
|
41
45
|
|
42
46
|
# Parsed headers. This only returns the query parameters that are defined in the OpenAPI spec.
|
47
|
+
# @return [Hash<String, anything>]
|
43
48
|
def parsed_headers
|
44
|
-
parsed_values[:headers]
|
49
|
+
@parsed_values[:headers]
|
45
50
|
end
|
46
51
|
|
47
52
|
# Parsed cookies. This only returns the query parameters that are defined in the OpenAPI spec.
|
53
|
+
# @return [Hash<String, anything>]
|
48
54
|
def parsed_cookies
|
49
|
-
parsed_values[:cookies]
|
55
|
+
@parsed_values[:cookies]
|
50
56
|
end
|
51
57
|
|
52
58
|
# Parsed body. This parses the body according to the content type.
|
53
59
|
# Note that this returns the hole body, not only the fields that are defined in the OpenAPI spec.
|
54
60
|
# You can use JSON Schemas `additionalProperties` or `unevaluatedProperties` to
|
55
61
|
# returns a validation error if the body contains unknown fields.
|
62
|
+
# @return [Hash<String, anything>]
|
56
63
|
def parsed_body
|
57
|
-
parsed_values[:body]
|
64
|
+
@parsed_values[:body]
|
58
65
|
end
|
59
66
|
|
60
67
|
# Checks if the request is valid.
|
@@ -74,6 +81,7 @@ module OpenapiFirst
|
|
74
81
|
|
75
82
|
# Merged path, query, body parameters.
|
76
83
|
# Here path has the highest precedence, then query, then body.
|
84
|
+
# @return [Hash<String, anything>]
|
77
85
|
def parsed_params
|
78
86
|
@parsed_params ||= parsed_body.merge(parsed_query, parsed_path_parameters)
|
79
87
|
end
|
@@ -15,10 +15,23 @@ module OpenapiFirst
|
|
15
15
|
@response_definition = response_definition
|
16
16
|
end
|
17
17
|
|
18
|
-
|
18
|
+
# A Failure object if the response is invalid
|
19
|
+
# @return [Failure, nil]
|
20
|
+
attr_reader :error
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
+
# The response definition if this response is defined in the API description
|
23
|
+
# @return [Response, nil]
|
24
|
+
attr_reader :response_definition
|
25
|
+
|
26
|
+
# The parsed headers
|
27
|
+
# @!method parsed_headers
|
28
|
+
# @return [Hash<String,anything>]
|
29
|
+
def_delegator :@parsed_values, :headers, :parsed_headers
|
30
|
+
|
31
|
+
# The parsed body
|
32
|
+
# @!method parsed_body
|
33
|
+
# @return [Hash<String,anything>]
|
34
|
+
def_delegator :@parsed_values, :body, :parsed_body
|
22
35
|
|
23
36
|
# Checks if the response is valid.
|
24
37
|
# @return [Boolean] true if the response is valid, false otherwise.
|
@@ -26,6 +39,8 @@ module OpenapiFirst
|
|
26
39
|
error.nil?
|
27
40
|
end
|
28
41
|
|
42
|
+
# Checks if the response is invalid.
|
43
|
+
# @return [Boolean]
|
29
44
|
def invalid?
|
30
45
|
!valid?
|
31
46
|
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: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Haller
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-07-
|
11
|
+
date: 2024-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hana
|