ota42y / openapi_parser

validate and coerce parameter using OpenAPI3 definition
MIT License
120 stars 86 forks source link

Validation fails for embedded JSON schema #77

Open lyubo1 opened 4 years ago

lyubo1 commented 4 years ago

Hello,

I'm working on building some validation for an Open Service Broker, where the broker API schema is defined using OpenAPI v3.0.0.

It allows for JSON schema to be referenced in the broker api spec itself.

Here is an example:

"schemas": {
    "service_instance": {
    "create": {
        "parameters": {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "type": "object",
        "properties": {
            "billing-account": {
            "description": "Billing account number used to charge use of shared fake server.",
            "type": "string"
            }
        }
        }
    },

When running the validation, in OpenAPIParser::SchemaValidator#validate_schema, I see the following error:

   NoMethodError:
       undefined method `any_of' for #

Looking further, the remote reference is properly resolved and the schema draft is fetched as defined in the openapi spec, unfortunately validate_schema doesn't know how to use the schema object to validate the value, especially because the schema is JSON schema.

In validate_schema(schema, value) the passed schema parameter is of type OpenAPIParser::Schemas::OpenAPI and contains the JSON schema draft and value parameter contains the schema definition itself, e.g. schema['service_instaces']['create']['parameters']

I'm using https://github.com/interagent/committee in our specs and looking for suggestions on how to handle this case? Thanks

lyubo1 commented 4 years ago

To reproduce

# cd openapi-parser
# bundler install
# ruby test.rb

require 'rubygems'
require 'bundler'

Bundler.require

require 'openapi_parser'
require 'open-uri'
require 'yaml'

openapi_yaml_schema = URI('https://raw.githubusercontent.com/openservicebrokerapi/servicebroker/master/openapi.yaml').read
root = OpenAPIParser.parse(YAML.load(openapi_yaml_schema))

response_body = {"services"=>
    [{"id"=>"service-id",
      "name"=>"service-name",
      "description"=>"service description",
      "plans"=>
       [{"id"=>"plan-id",
         "name"=>"plan-name",
         "description"=>"plan description",
         "schemas"=>
          {"service_instance"=>
            {"create"=>
              {"parameters"=>
                {"$schema"=>"http://json-schema.org/draft-04/schema#",
                 "type"=>"object",
                 "required"=>["test-prop"],
                 "properties"=>{"test-prop"=>{"type"=>"string"}}}},
             "update"=>
              {"parameters"=>
                {"$schema"=>"http://json-schema.org/draft-04/schema#"}}},
           "service_binding"=>
            {"create"=>
              {"parameters"=>
                {"$schema"=>"http://json-schema.org/draft-04/schema#"}}}}}]}]}
request_operation = root.request_operation(:get, '/v2/catalog')
response_headers = {
    "Content-Type"=>"application/json;charset=utf-8",
}
validation_response_body = OpenAPIParser::RequestOperation::ValidatableResponseBody.new(200, response_body, response_headers)
request_operation.validate_response_body(validation_response_body)