I am using jsonschema 4.17.3 with Python 3.7 to validate a JSON file. In this project I am facing a challenge, where I need to implement an OR relationship. This means in my case, that I require from 2 items that, either one of them is present, or both. This can be best explained with the JSON snippets below. Here, I want to be able to configure tasks for a tool. The first task is to download_data from a REST-API server and the second task is to upload_data the resulting (downloaded and converted data) to a relational database system. So, both tasks can occur together if I require my Python tool to do it all in one go.
{
"tasks":{
"download_data":{
"targetdir": "data\\",
"Rest":
{
"type": "MyRestAPIProvider",
"server": "MyServerName",
"api_version": "9.99",
"source": "production",
"user": "de.my.corp\\User",
"password": "!SecretPasswort!"
}
},
"upload_data":{
"zip": "",
"database_server":{
"host":"MyDatabaseHost",
"port":"99999",
"database":"MyDatabase",
"user":"MyDatabaseUser",
"password":"MySecretPassword"
}
}
}
}
...but each task can also occur by itself alone (if I want to only download data, or only upload data that I have downloaded previously:
JSON sample to only download data:
{
"tasks":{
"download_data":{
"targetdir": "data\\",
"Rest":
{
"type": "MyRestAPIProvider",
"server": "MyServerName",
"api_version": "9.99",
"source": "production",
"user": "de.my.corp\\User",
"password": "!SecretPasswort!"
}
}
}
}
}
JSON sample to only upload data:
{
"tasks":{
"upload_report":{
"zip": "",
"database_server":{
"host":"MyDatabaseHost",
"port":"99999",
"database":"MyDatabase",
"user":"MyDatabaseUser",
"password":"MySecretPassword"
}
}
}
}
The best JSON Schema for validating this is the JSON schema shown below. Where I actually use 3 JSON Schema files of the listing below:
- A JSON schema containing definitions for both tasks as shown below
- A JSON schema containing only the definitions for the download_data task (an extract from listing below)
- A JSON schema containing only the definitions for the upload_data task (an extract from listing below)
Next, I try to validate a given JSON file against one of the 3 files and pronounce the JSON file valid, if it succeeded on 1., 2. or 3.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"tasks": {
"type": "object",
"properties": {
"download_data": {
"type": "object",
"properties": {
"targetdir": { "type": "string" },
"Rest": {
"type": "object",
"properties": {
"type": { "type": "string" },
"server": { "type": "string" },
"api_version": { "type": "string" },
"source": { "type": "string" },
"user": { "type": "string" },
"password": { "type": "string" }
}, "required": ["type", "server", "api_version", "source", "user", "password"]
}
},
"required": ["targetdir", "Rest"]
},
"upload_data": {
"type": "object",
"properties": {
"zip": { "type": "string" },
"database_server": {
"type": "object",
"properties": {
"host": { "type": "string" },
"port": { "type": "string" },
"database": { "type": "string" },
"user": { "type": "string" },
"password": { "type": "string" }
}, "required": ["host", "port", "database", "user", "password"
]
}
}, "required": ["zip", "database_server"]
}
}, "required": ["download_report", "upload_report"]
}
},
"required": ["tasks"]
}
My question is: What JSON schema representation do I need to validate this with only 1 JSON schema file, which should validate OK, if only one of the tasks is present, or both. But should fail, if there is no task present.
Bonus question: Is there a good recommended resource to find such non-trivial cases and learn from examples that might be available in a reference.
I have obviously been playing with this problem for a while before coming here. But so far, I have found only simple 101 style docs (https://json-schema.org/learn/getting-started-step-by-step) that do not seem to cover non-trivial cases like mine :-(