Json Schema example for oneOf objects

74,068

Solution 1

Try this:

{
    "description" : "schema validating people and vehicles",
    "type" : "object",
    "oneOf" : [
       {
        "type" : "object",
        "properties" : {
            "firstName" : {
                "type" : "string"
            },
            "lastName" : {
                "type" : "string"
            },
            "sport" : {
                "type" : "string"
            }
          }
      }, 
      {
        "type" : "object",
        "properties" : {
            "vehicle" : {
                "type" : "string"
            },
            "price" : {
                "type" : "integer"
            }
        },
        "additionalProperties":false
     }
]
}

Solution 2

oneOf need to be used inside a schema to work.

Inside properties, it's like another property called "oneOf" without the effect you want.

Share:
74,068

Related videos on Youtube

Stanimirovv
Author by

Stanimirovv

Wannabe developer with a stupid sense of humour.

Updated on August 18, 2021

Comments

  • Stanimirovv
    Stanimirovv over 2 years

    I am trying to figure out how oneOf works by building a schema which validates two different object types. For example a person (firstname, lastname, sport) and vehicles (type, cost).

    Here are some sample objects:

    {"firstName":"John", "lastName":"Doe", "sport": "football"}
    
    {"vehicle":"car", "price":20000}
    

    The question is what have I done wrongly and how can I fix it. Here is the schema:

    {
        "description": "schema validating people and vehicles", 
        "$schema": "http://json-schema.org/draft-04/schema#",
        "type": "object",
        "required": [ "oneOf" ],
        "properties": { "oneOf": [
            {
                "firstName": {"type": "string"}, 
                "lastName": {"type": "string"}, 
                "sport": {"type": "string"}
            }, 
            {
                "vehicle": {"type": "string"}, 
                "price":{"type": "integer"} 
            }
         ]
       }
    }
    

    When I try to validate it in this parser:

    https://json-schema-validator.herokuapp.com/
    

    I get the following error:

       [ {
      "level" : "fatal",
      "message" : "invalid JSON Schema, cannot continue\nSyntax errors:\n[ {\n  \"level\" : \"error\",\n  \"schema\" : {\n    \"loadingURI\" : \"#\",\n    \"pointer\" : \"/properties/oneOf\"\n  },\n  \"domain\" : \"syntax\",\n  \"message\" : \"JSON value is of type array, not a JSON Schema (expected an object)\",\n  \"found\" : \"array\"\n} ]",
      "info" : "other messages follow (if any)"
    }, {
      "level" : "error",
      "schema" : {
        "loadingURI" : "#",
        "pointer" : "/properties/oneOf"
      },
      "domain" : "syntax",
      "message" : "JSON value is of type array, not a JSON Schema (expected an object)",
      "found" : "array"
    } ]
    
  • Relequestual
    Relequestual over 9 years
    I'm not saying your wrong, but can you provide a source for this information please? =]
  • gursahib.singh.sahni
    gursahib.singh.sahni almost 7 years
    Does oneOf help in validating the request? I can't see any jackson annotation for oneOf during pojo conversion
  • jruizaranguren
    jruizaranguren almost 7 years
    @gursahib.singh.sahni, that is a jackson specific problem. It is not easy to translate oneOf semantics to some programming languages such as java. You need some construct like Disjoint sets, Discriminated Unions, Union Types... that other languages have.
  • gursahib.singh.sahni
    gursahib.singh.sahni almost 7 years
    @jruizaranguren there any library other than jackson that handles this case ? or else we would have to add custom validators in our codebase.
  • davidtgq
    davidtgq over 6 years
    Well it makes sense from deduction of what properties does, i.e. why would properties ever make a special case for keys named oneOf? Pretty much common sense it works this way now that I think of it. Thanks for the explanation.
  • Alireza Mirian
    Alireza Mirian over 6 years
    Is it required to have "type" : "object" on the root? It doesn't make much sense.
  • jruizaranguren
    jruizaranguren over 6 years
    @AlirezaMirian, if you do not explicitly specify it, any other type would satisfy the specification, because "oneOf" only applies to types. It is ignored for other types.
  • Ark-kun
    Ark-kun over 5 years
    @jruizaranguren >""oneOf" only applies to types. It is ignored for other types" - It's wrong. But in this particular case, "type: object" is needed, because the specs inside oneOf do not have any type information and the type should be specified somewhere.
  • jruizaranguren
    jruizaranguren over 5 years
    @Ark-kun, it is convenient, not required. If type is omitted, unwanted objects may be validated. For instance, an empty object validates my schema, which is not probably what you want. But the question was about oneOf usage and syntax.
  • Ark-kun
    Ark-kun over 5 years
    @jruizaranguren >"an empty object validates my schema, which is not probably what you want" - Well, your second schema has no required properties, so an empty object is valid against it. What if you added required properties? AFAIK, with oneOf, you create multiple object schema variants by adding the contents of a oneOf section to the surrounding schema node. All resulting schema variant must be valid schemas and for the object to be considered validated against the schema, it needs to be valid against exactly one variant.
  • jruizaranguren
    jruizaranguren over 5 years
    @Ark-kun, we can think of many what-if situations, and your explanations of json-schema are valid. But the question is about oneOf syntax, not about modeling a concrete problem. I find this discussion off-topic.
  • Ark-kun
    Ark-kun over 5 years
    I guess I just do not understand what exactly you meant by ""oneOf" only applies to types. It is ignored for other types.". And I consider "it is convenient, not required." to be wrong. The type must be set either outside oneOf or inside all oneOf variants. Not omitted. Not specified both ways.
  • jruizaranguren
    jruizaranguren over 5 years
    ok, I understand the issue. By saying "it is convenient, not required" I mean the standard does not enforce its usage. As most of things in json-schema, it must be read as: "if your data is an object, then apply the oneOf constraint", "if your data is not an object, ignore this clause".
  • jruizaranguren
    jruizaranguren over 5 years
    And the standard also says that each element in oneOf must be a valid json-schema. Thus, specifying the type is correct. It may help defining the constraints.
  • Moondoggy
    Moondoggy almost 3 years
    This is what I found also. oneOf inside of properties does not work.
  • justin.m.chase
    justin.m.chase almost 3 years
    Can you have a oneOf and properties on the top type?
  • jruizaranguren
    jruizaranguren almost 3 years
    @justin.m.chase, Should be that a new question to S.O.?