templates/app/lib/plug_app/middleware/openapi_validation.rb in hephaestus-0.6.0 vs templates/app/lib/plug_app/middleware/openapi_validation.rb in hephaestus-0.6.1
- old
+ new
@@ -10,45 +10,74 @@
SPEC_PATH = Rails.root.join("lib/plug_app/schemas/api/2023-03-06/openapi.json")
SPEC = OpenapiFirst.load(SPEC_PATH)
def initialize(app)
@app = app
- @response_validator = OpenapiFirst::ResponseValidator.new(SPEC)
- @request_validator = OpenapiFirst::RequestValidation.new(->(_env) {}, spec: SPEC, raise_error: true)
end
def call(env)
request = Rack::Request.new(env)
- if request.path.starts_with?(API_PATH_PREFIX)
+ return @app.call(env) unless request.path.starts_with?(API_PATH_PREFIX) && request.path.exclude?("/settings")
+
+ begin
# force content-type to JSON
- if env["CONTENT_TYPE"] == "application/x-www-form-urlencoded"
- env["CONTENT_TYPE"] = "application/json"
- end
+ env["CONTENT_TYPE"] = "application/json" if env["CONTENT_TYPE"] != "application/json"
- begin
- @request_validator.call(env)
- # response = @app.call(env)
- # @response_validator.validate(request, response)
- rescue OpenapiFirst::NotFoundError
- PlugApp::Middleware::NotFound.new.call(env)
- rescue OpenapiFirst::RequestInvalidError => e
- error_hsh = ::ErrorSerializer.format(e.message)
- Rails.logger.error(error_hsh) if print_user_api_errors?
- return [PlugApp::HTTP::BAD_REQUEST_I, { "Content-Type" => "application/json" }, [error_hsh]]
- rescue StandardError => e
- raise e unless Rails.env.production?
+ validated_request = SPEC.validate_request(request)
- logger.error(
- "openapi.request_validation.error",
- path: request.path,
- method: request.env["REQUEST_METHOD"],
- error_message: e.message,
- )
+ return @app.call(env) if validated_request.valid?
+
+ case validated_request.error
+ when OpenapiFirst::Schema::ValidationError
+ error_arr = format_arr(validated_request.error.errors.map(&:error))
+ Rails.logger.error(error_arr) if print_user_api_errors?
+ [PlugApp::HTTP::BAD_REQUEST_I, { "Content-Type" => "application/json" }, [error_arr]]
+ else
+ case validated_request.error.error_type
+ when :not_found
+ [PlugApp::HTTP::NOT_FOUND_I, { "Content-Type" => "application/json" }, [format_str("Not Found")]]
+ else
+ error_message = if validated_request.error.errors.present?
+ format_arr(validated_request.error.errors.map(&:error))
+ else
+ format_str(validated_request.error.message)
+ end
+
+ Rails.logger.error(error_message) if print_user_api_errors?
+ [PlugApp::HTTP::BAD_REQUEST_I, { "Content-Type" => "application/json" }, [error_message]]
+ end
end
+ rescue StandardError => e
+ raise e unless Rails.env.production?
+
+ logger.error(
+ "openapi.request_validation.error",
+ path: request.path,
+ method: request.env["REQUEST_METHOD"],
+ error_message: e.message,
+ )
end
+ end
- @app.call(env)
+ private def format_str(error)
+ {
+ errors: [
+ {
+ message: error,
+ },
+ ],
+ }.to_json
+ end
+
+ private def format_arr(errors)
+ {
+ errors: errors.each_with_object([]) do |error, arr|
+ arr << {
+ message: error,
+ }
+ end,
+ }.to_json
end
end
end
end