openapi_first 1.0.0.beta5 → 1.0.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/.github/workflows/ruby.yml +2 -1
- data/CHANGELOG.md +23 -2
- data/Gemfile +2 -0
- data/Gemfile.lock +16 -18
- data/Gemfile.rack2 +15 -0
- data/Gemfile.rack2.lock +99 -0
- data/README.md +99 -130
- data/lib/openapi_first/body_parser.rb +29 -0
- data/lib/openapi_first/configuration.rb +20 -0
- data/lib/openapi_first/definition/cookie_parameters.rb +12 -0
- data/lib/openapi_first/definition/header_parameters.rb +12 -0
- data/lib/openapi_first/definition/operation.rb +116 -0
- data/lib/openapi_first/definition/parameters.rb +47 -0
- data/lib/openapi_first/definition/path_item.rb +32 -0
- data/lib/openapi_first/definition/path_parameters.rb +12 -0
- data/lib/openapi_first/definition/query_parameters.rb +12 -0
- data/lib/openapi_first/definition/request_body.rb +43 -0
- data/lib/openapi_first/definition/response.rb +25 -0
- data/lib/openapi_first/definition/responses.rb +83 -0
- data/lib/openapi_first/definition.rb +61 -8
- data/lib/openapi_first/error_response.rb +22 -27
- data/lib/openapi_first/errors.rb +2 -14
- data/lib/openapi_first/failure.rb +55 -0
- data/lib/openapi_first/middlewares/request_validation.rb +52 -0
- data/lib/openapi_first/middlewares/response_validation.rb +35 -0
- data/lib/openapi_first/plugins/default/error_response.rb +74 -0
- data/lib/openapi_first/plugins/default.rb +11 -0
- data/lib/openapi_first/plugins/jsonapi/error_response.rb +58 -0
- data/lib/openapi_first/plugins/jsonapi.rb +11 -0
- data/lib/openapi_first/plugins.rb +9 -7
- data/lib/openapi_first/request_validation/request_body_validator.rb +41 -0
- data/lib/openapi_first/request_validation/validator.rb +81 -0
- data/lib/openapi_first/response_validation/validator.rb +101 -0
- data/lib/openapi_first/runtime_request.rb +84 -0
- data/lib/openapi_first/runtime_response.rb +31 -0
- data/lib/openapi_first/schema/validation_error.rb +18 -0
- data/lib/openapi_first/schema/validation_result.rb +32 -0
- data/lib/openapi_first/{json_schema.rb → schema.rb} +9 -5
- data/lib/openapi_first/version.rb +1 -1
- data/lib/openapi_first.rb +32 -28
- data/openapi_first.gemspec +10 -9
- metadata +55 -67
- data/.rspec +0 -3
- data/.rubocop.yml +0 -14
- data/Rakefile +0 -15
- data/benchmarks/Gemfile +0 -16
- data/benchmarks/Gemfile.lock +0 -142
- data/benchmarks/README.md +0 -29
- data/benchmarks/apps/committee_with_hanami_api.ru +0 -26
- data/benchmarks/apps/committee_with_response_validation.ru +0 -29
- data/benchmarks/apps/committee_with_sinatra.ru +0 -31
- data/benchmarks/apps/grape.ru +0 -21
- data/benchmarks/apps/hanami_api.ru +0 -21
- data/benchmarks/apps/hanami_router.ru +0 -14
- data/benchmarks/apps/openapi.yaml +0 -268
- data/benchmarks/apps/openapi_first_with_hanami_api.ru +0 -24
- data/benchmarks/apps/openapi_first_with_plain_rack.ru +0 -32
- data/benchmarks/apps/openapi_first_with_response_validation.ru +0 -25
- data/benchmarks/apps/openapi_first_with_sinatra.ru +0 -29
- data/benchmarks/apps/roda.ru +0 -27
- data/benchmarks/apps/sinatra.ru +0 -26
- data/benchmarks/apps/syro.ru +0 -25
- data/benchmarks/benchmark-wrk.sh +0 -3
- data/benchmarks/benchmarks.rb +0 -48
- data/benchmarks/post.lua +0 -3
- data/bin/console +0 -15
- data/bin/setup +0 -8
- data/examples/README.md +0 -13
- data/examples/app.rb +0 -18
- data/examples/config.ru +0 -7
- data/examples/openapi.yaml +0 -29
- data/lib/openapi_first/body_parser_middleware.rb +0 -40
- data/lib/openapi_first/config.rb +0 -20
- data/lib/openapi_first/error_responses/default.rb +0 -58
- data/lib/openapi_first/error_responses/json_api.rb +0 -58
- data/lib/openapi_first/json_schema/result.rb +0 -17
- data/lib/openapi_first/operation.rb +0 -170
- data/lib/openapi_first/request_body_validator.rb +0 -41
- data/lib/openapi_first/request_validation.rb +0 -118
- data/lib/openapi_first/request_validation_error.rb +0 -31
- data/lib/openapi_first/response_validation.rb +0 -93
- data/lib/openapi_first/response_validator.rb +0 -21
- data/lib/openapi_first/router.rb +0 -102
- data/lib/openapi_first/string_keyed_hash.rb +0 -20
- data/lib/openapi_first/use_router.rb +0 -18
data/lib/openapi_first/router.rb
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rack'
|
4
|
-
require 'multi_json'
|
5
|
-
require 'hanami/router'
|
6
|
-
require_relative 'body_parser_middleware'
|
7
|
-
|
8
|
-
module OpenapiFirst
|
9
|
-
class Router
|
10
|
-
# The unconverted path parameters before they are converted to the types defined in the API description
|
11
|
-
RAW_PATH_PARAMS = 'openapi.raw_path_params'
|
12
|
-
|
13
|
-
def initialize(
|
14
|
-
app,
|
15
|
-
options
|
16
|
-
)
|
17
|
-
@app = app
|
18
|
-
@raise = options.fetch(:raise_error, false)
|
19
|
-
@not_found = options.fetch(:not_found, :halt)
|
20
|
-
@error_response_class = options.fetch(:error_response, Config.default_options.error_response)
|
21
|
-
spec = options.fetch(:spec)
|
22
|
-
raise "You have to pass spec: when initializing #{self.class}" unless spec
|
23
|
-
|
24
|
-
spec = OpenapiFirst.load(spec) unless spec.is_a?(Definition)
|
25
|
-
|
26
|
-
@filepath = spec.filepath
|
27
|
-
@router = build_router(spec.operations)
|
28
|
-
end
|
29
|
-
|
30
|
-
def call(env)
|
31
|
-
env[OPERATION] = nil
|
32
|
-
response = call_router(env)
|
33
|
-
if env[OPERATION].nil?
|
34
|
-
raise_error(env) if @raise
|
35
|
-
|
36
|
-
return @app.call(env) if @not_found == :continue
|
37
|
-
end
|
38
|
-
|
39
|
-
response
|
40
|
-
end
|
41
|
-
|
42
|
-
ORIGINAL_PATH = 'openapi_first.path_info'
|
43
|
-
private_constant :ORIGINAL_PATH
|
44
|
-
|
45
|
-
ROUTER_PARSED_BODY = 'router.parsed_body'
|
46
|
-
private_constant :ROUTER_PARSED_BODY
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def raise_error(env)
|
51
|
-
req = Rack::Request.new(env)
|
52
|
-
msg =
|
53
|
-
"Could not find definition for #{req.request_method} '#{
|
54
|
-
req.path
|
55
|
-
}' in API description #{@filepath}"
|
56
|
-
raise NotFoundError, msg
|
57
|
-
end
|
58
|
-
|
59
|
-
def call_router(env)
|
60
|
-
# Changing and restoring PATH_INFO is needed, because Hanami::Router does not respect existing script_path
|
61
|
-
env[ORIGINAL_PATH] = env[Rack::PATH_INFO]
|
62
|
-
env[Rack::PATH_INFO] = Rack::Request.new(env).path
|
63
|
-
@router.call(env)
|
64
|
-
rescue BodyParsingError => e
|
65
|
-
message = e.message
|
66
|
-
raise RequestInvalidError, message if @raise
|
67
|
-
|
68
|
-
error = RequestValidationError.new(status: 400, location: :body, message:)
|
69
|
-
@error_response_class.new(env, error).render
|
70
|
-
ensure
|
71
|
-
env[Rack::PATH_INFO] = env.delete(ORIGINAL_PATH) if env[ORIGINAL_PATH]
|
72
|
-
end
|
73
|
-
|
74
|
-
def build_router(operations)
|
75
|
-
router = Hanami::Router.new.tap do |r|
|
76
|
-
operations.each do |operation|
|
77
|
-
normalized_path = operation.path.gsub('{', ':').gsub('}', '')
|
78
|
-
r.public_send(
|
79
|
-
operation.method,
|
80
|
-
normalized_path,
|
81
|
-
to: build_route(operation)
|
82
|
-
)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
Rack::Builder.app do
|
86
|
-
use(BodyParserMiddleware)
|
87
|
-
run router
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def build_route(operation)
|
92
|
-
lambda do |env|
|
93
|
-
env[OPERATION] = operation
|
94
|
-
path_info = env.delete(ORIGINAL_PATH)
|
95
|
-
env[REQUEST_BODY] = env.delete(ROUTER_PARSED_BODY) if env.key?(ROUTER_PARSED_BODY)
|
96
|
-
env[RAW_PATH_PARAMS] = env['router.params']
|
97
|
-
env[Rack::PATH_INFO] = path_info
|
98
|
-
@app.call(env)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module OpenapiFirst
|
4
|
-
class StringKeyedHash
|
5
|
-
extend Forwardable
|
6
|
-
def_delegators :@orig, :empty?
|
7
|
-
|
8
|
-
def initialize(original)
|
9
|
-
@orig = original
|
10
|
-
end
|
11
|
-
|
12
|
-
def key?(key)
|
13
|
-
@orig.key?(key.to_sym)
|
14
|
-
end
|
15
|
-
|
16
|
-
def [](key)
|
17
|
-
@orig[key.to_sym]
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module OpenapiFirst
|
4
|
-
module UseRouter
|
5
|
-
def initialize(app, options = {})
|
6
|
-
@app = app
|
7
|
-
@options = options
|
8
|
-
super
|
9
|
-
end
|
10
|
-
|
11
|
-
def call(env)
|
12
|
-
return super if env.key?(OPERATION)
|
13
|
-
|
14
|
-
@router ||= Router.new(->(e) { super(e) }, @options)
|
15
|
-
@router.call(env)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|