openapi-core icon indicating copy to clipboard operation
openapi-core copied to clipboard

referencing a json-schema from openapi3

Open sanderegg opened this issue 6 years ago • 15 comments

Hello,

I am currently in the process of creating a python based REST api. I wrote an openapi 3.0 interface that reference an external json-schema file using $ref: 'test.json' (openapiref)[https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject] as I thought this is supposed to be possible.

Now I wanted to use openapi-core to validate requests and responses but I hit a problem which is that the validation of my openapi interface file does not go through because I get an error of type:

{'description': 'some external json', 'content': {'application/json': {'schema': {'$ref': './test.json', 'x-scope': ['file:///c:/Users/anderegg/Documents/dev/OSPARC/jsonschematest/testapi.yaml']}}}}
is not valid under any of the given schemas

Failed validating 'oneOf' in schema['properties']['paths']['patternProperties']['^/']['properties']['get']['properties']['responses']['properties']['default']:
    {'oneOf': [{'$ref': '#/definitions/response'},
               {'$ref': '#/definitions/reference'}]}

On instance['paths']['/']['get']['responses']['default']:
    {'content': {'application/json': {'schema': {'$ref': './test.json',
                                                 'x-scope': ['file:///c:/Users/anderegg/Documents/dev/OSPARC/jsonschematest/testapi.yaml']}}},
     'description': 'some external json'}

my example openapi interface looks like this:

# test.yaml
openapi: "3.0.0"
info:
  description: This is a test api
  version: 1.0.0
  title: Test API

paths:
  /:
    get:
      tags: 
        - users
      summary: Returns a nice greeting
      description: Returns a nice greeting
      operationId: root_get
      responses:
        default:
          description: some external json
          content:
            application/json:
              schema:
                $ref: './test.json'

and my example json-schema:

// test.json
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Test",
    "type": ["string", "null"],
    "format": "date-time"
}

Now I understand the problem comes from factories.py:SpecFactory:create where openapi_spec_validator is failing in validating my file because the ref does not follow #/something.

Am I wrong in thinking I can direclty reference a JSON schema? If not, is it possible to disable the spec validation from client side? Or should I change something in the way I reference it?

Thanks for any input on this...

sanderegg avatar Aug 30 '18 08:08 sanderegg

@sanderegg hi. It is possible to use external files. You need to pass additional parameter spec_url='file:///path/to/your/openapi.yaml' when creating spec.

Your test.json is not valid because there is no null type in OpenAPI 3. See nullable

p1c2u avatar Aug 30 '18 09:08 p1c2u

Hi @p1c2u , Yes I did this, I actually realise I forgot to show the python code:

from openapi_spec_validator import validate_spec, factories
from openapi_core import create_spec
from openapi_core.shortcuts import RequestValidator
from pathlib import Path
import yaml
import json

SPEC_FILE = Path(__file__).parent / "testapi.yaml"
with SPEC_FILE.open() as fp:
    specification_dict = yaml.load(fp)
uri = SPEC_FILE.as_uri()

try:
    # factories.config
    spec = create_spec(specification_dict, spec_url=uri)
    validator = RequestValidator(spec)
except Exception as err:
    print(err)

sanderegg avatar Aug 30 '18 09:08 sanderegg

The element of the document located on the same server should look like follow – $ref: 'test.json'

https://swagger.io/docs/specification/using-ref/#syntax

p1c2u avatar Aug 30 '18 09:08 p1c2u

I tried $ref: 'test.json' and $ref: './test.json' both return the same error as explained above. The latter works better in some other packages. Actually the problem is not in finding the file, this works. The problem is I think that it is not looking like:

{'oneOf': [{'$ref': '#/definitions/response'},
               {'$ref': '#/definitions/reference'}]}

sanderegg avatar Aug 30 '18 09:08 sanderegg

@sanderegg it works for me after fixing `null issue

f = open('testapi.yaml')
spec_dict = safe_load(f)
spec = create_spec(spec_dict, spec_url='file:///path/to/file/test.yaml')

p1c2u avatar Aug 30 '18 10:08 p1c2u

@p1c2u what do you mean fixing `null issue?

sanderegg avatar Aug 30 '18 11:08 sanderegg

@sanderegg see my first comment

p1c2u avatar Aug 30 '18 11:08 p1c2u

so you changed to

// test.json
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Test",
    "type": ["string"],
    "format": "date-time"
}

is that correct? cause for me I still get the very same error .

sanderegg avatar Aug 30 '18 13:08 sanderegg

There is no such keyword as $schema and type should be string

Here is valid:

// test.json
{
    "title": "Test",
    "type": "string",
    "format": "date-time",
    "nullable": true
}

p1c2u avatar Aug 30 '18 15:08 p1c2u

Ok, but then it is not anymore a json-schema but a openapi. So it is not possible to mix them together in that case.

sanderegg avatar Aug 30 '18 18:08 sanderegg

Hmm. What can I say more. It's OpenAPI library and OpenAPI schema is subset of JSONSchema

The Schema Object allows the definition of input and output data types. This object is an extended subset of the JSON Schema Specification Wright Draft 00.

p1c2u avatar Aug 30 '18 19:08 p1c2u

ok, so after hours of research it's actually possible folowing: this and this.

So, using a json-schema file, passing it through the json-schema-to-openapi converter and then in the openapi-validator. The node command line tool speccy actually validates an openapi with integrated json-schema inside using the -j flag.

sanderegg avatar Aug 31 '18 06:08 sanderegg

Thanks for the info. It's a bit hacky. "More Proper Solution" looks good. Now we need to wait for OpenAPI 3.1 release.

p1c2u avatar Aug 31 '18 11:08 p1c2u

What is the status of this issue? The incompatibility with JSONSchema is a disaster, especially with more complicated Schemata (with internal or external references).

HRogge avatar Mar 29 '19 13:03 HRogge

ok, so after hours of research it's actually possible folowing: this and this.

The above links appeared to have been moved to this and this .

thierrydallacroce avatar Aug 15 '19 16:08 thierrydallacroce