0

How can I hint the type of embedded objects in JSON Schema, analogous to xsi:type in XML Schema?

Example schema document:

{
    "type": "storeRequest",
    "properties": {
        "txid": {
            "description": "Transaction ID to prevent double committing",
            "type": "integer"
        },
        "objects": {
            "description": "Objects to store",
            "type": "array"
            "items": {
                "type": "object"
            },
            "minItems": 1,
            "uniqueItems": true
        },
    },
    "required": ["txid", "objects"]
}

This is a request the client sends to the server to store multiple objects in the database. Now how can I recursively validate the content of objects when it can contain more than one type of object. (Plymorphism, really).

vbence
  • 20,084
  • 9
  • 69
  • 118
  • I'd recommend you to use the OpenAPI support to polymorphism. I've written about it here: https://stackoverflow.com/questions/38626716/json-and-object-inheritance/46839490#46839490 – dbaltor Feb 18 '20 at 08:10
  • @dbaltor Thanks for the good advice. How much support does this feature have in the different generated client/server stubs? – vbence Feb 21 '20 at 12:54
  • 1
    Hi @vbence, haven't tried yet but it seems to support only client stubs as per this comment from the author: https://github.com/OpenAPITools/openapi-generator/pull/5120#issuecomment-588846548 – dbaltor Mar 03 '20 at 12:22

1 Answers1

1

There is not an equivalent to xsi:type in JSON-schema AFAIK. Perhaps the most JSON-schema idiomatic way to hint the existence of types would be the explicit definition of types as schemas and referencing them through $ref:

{
    "properties" : {
        "wheels" : {
            "type" : "array",
            "items" : "$ref" : "#/definitions/wheel"
        }
    }

    "definitions" : {
        "wheel" : {
            "type" : "object"
        }
    }
}

Another way could be to give a hint through enums :

    {
    "definitions" : {
        "vehicle" : {
            "properties" : {
                "type" : {
                    "enum" : ["car", "bike", "plane"]
                }
            }
        },
        "plane" : {
            "properties" : {
                "type" : {
                    "enum" : "plane"
                }
            }
            "allOf" : ["$ref" : "#/definitions/vehicle"]
        }
     }
   }

Finally you can also add whatever tag you can process to a JSON-schema and follow your conventions.

Be aware that you are not going to find an equivalent translation between typical object oriented programming languages (java, C#) inheritance semantics and JSON-schema.

jruizaranguren
  • 12,679
  • 7
  • 55
  • 73