raml-org / raml-spec

RAML Specification
http://raml.org
3.87k stars 859 forks source link

Clarify validate inner elements of JSON Schema #378

Open fededonna opened 8 years ago

fededonna commented 8 years ago

According to the following JSON Schema

{
    "id": "http://some.site.somewhere/entry-schema#",
    "$schema": "http://json-schema.org/draft-04/schema#",
    "description": "schema for an animal or a person",
    "type": "object",
    "oneOf": [
       { "$ref": "#/definitions/Person" },
       { "$ref": "#/definitions/Animal" }
    ], 
    "definitions": {
        "Person": {
            "type": "object",
            "properties":{
              "name": {
                "type": "string"
              }
            },
            "required":["name"]
        },
        "Animal": {
            "type": "object",
            "properties":{
              "specie": {
                  "type":"string"
              }
            },
            "required": ["specie"]

        }
    }
}

The allowed valid elements are Animal and Person so the following JSONs are valid:

{
    "specie": "Lion"
}
{
    "name": "John Doe"
}    

So we can reference types as:

type: Animal
schema: !include type-library.json#Animal
type: Person
schema: !include type-library.json#Person

But you are not allowed to validate inner elements as:

type: specie
schema: !include type-library.json#specie

Is this assumption correct? This can not be validated because it can be an inner type and reference to siblings and the extraction of this is not possible without transforming the JSON in a weird way.

usarid commented 8 years ago

@fededonna I don't know what constructs like this

type: Animal
schema: !include type-library.json#Animal

mean. Perhaps you mean

types: 
  Animal:
    schema: !include type-library.json#Animal

?

Your question then becomes whether one can use references to parts of a schema when they depend on things outside that part.

fededonna commented 8 years ago

yes, it means the second construct. The json schema validates anyof so it can not validate just an element of that.

The main question is about how to validate examples if they are written in a yaml and the type was defines with an schema and how to validate json payloads if they are written in xml or json vs a type-system defined type.

so the main concerns are:

1) Validate example between different types (AKA type conversion) 2) Validate payloads of different types (also type-conversion)

sichvoge commented 8 years ago

@fededonna does all this relate to issues #377 & #379? And are your main concerns in the end not the same?

fededonna commented 8 years ago

Yes, in fact they are. The concern main focus is about validating different types and also converting the examples in a given type to the mediaType of the resource.

Imagine that I give the type person in Yaml and define my resource to accept application/json then the example shown in the console, if it's given in a yaml way, will be useless because my service won't accept the payload in that way.

Thanks in advance.

sichvoge commented 8 years ago

Indeed; thanks for clarification @fededonna.

petrochenko-pavel-a commented 8 years ago

Your question then becomes whether one can use references to parts of a schema when they depend >on things outside that part.

As for me it definitely should be possible. As for JSON schema we are doing special transformation for this already.

Imagine that I give the type person in Yaml and define my resource to accept application/json then the >example shown in the console, if it's given in a yaml way, will be useless because my service won't >accept the payload in that way.

As for me console should be able to display different representations of the example (do not depending from its original form)

usarid commented 8 years ago

This specific issue is about using JSON schema elements vs the whole JSON schema. Everything else should be in another issue.

JSON schema can only validate JSON. So if your data instance is not JSON, processors won't in general be able to validate it according to the JSON schema, and unless they have a way to convert it on their own, they'll throw an error. RAML will only be concerned with enforcing that processors MUST validate JSON data according to the JSON schema if the JSON schema is given; it will not tell processors what to do in case the JSON schema is given but the data is not JSON.

If the instance to be validated is itself within the scope of RAML, specifically because it's an example that needs validating, then it's a separate issue how to convert an example given in non-JSON format to JSON so validation can occur; we should have issues for doing this for YAML-formatted examples and for XML-formatted examples. We do have them for for validating YAML-formatted examples and for XML-formatted examples against RAML data types.

But back to this issue: @petrochenko-pavel-a can you please explain what you think is the full answer of how to use parts of schema when they refer to other parts? Or is that coming in response to a different issue somewhere?

petrochenko-pavel-a commented 8 years ago

JSON schema can only validate JSON. So if your data instance is not JSON, processors won't in general be able to validate it according to the JSON schema, and unless they have a way to convert it on their own, they'll throw an error

This is absolutely true.

then it's a separate issue how to convert an example given in non-JSON format to JSON so validation >can occur; we should have issues for doing this for YAML-formatted examples

YAML example always can be mapped to JSON in 1:1 (according to XML examples, my guess is that we should not allow to check them against JSON schemas (same for JSON examples + XSD)).

But back to this issue: @petrochenko-pavel-a can you please explain what you think is the full answer of how to use parts of schema when they refer to other parts?

As for me the full answer is to build a transformation of the original schema which exposes needed part of the schema and is still valid.

sichvoge commented 8 years ago

Just for me noob :) When you define that

types: 
  Animal:
    schema: !include type-library.json#Animal

Where does that depend on things outside that part. Is it not equivalent to the following???

types: 
  Animal:
    schema: |
        {
            "type": "object",
            "properties":{
              "specie": {
                  "type":"string"
              }
            },
            "required": ["specie"]

        }
petrochenko-pavel-a commented 8 years ago

no, because original @fededonna schema does not contains specie on this level. But generally in a lot of cases it is similar, but if your inner fragment contains references to outer parts you need to keep them working.

Regards, Pavel