Creating a hierarchy of JSON schemas - json

I'm working on structuring some JSON data with information from different types of sources. I am focusing on only one type of source, documents, and I have a few data points collected and ready. So I decided I should try and write a JSON schema for data regarding the documents.
The first four properties, id, name, type and url must be present regardless of the type of source, but the other information contained in each varies. I would like to store all of them in the same database though. I suppose it will be of interest to write a schema for each of the other types of sources at a later point.
I am quite new to working with JSON, and the difficulty at the moment is understanding how I can fit these schemas together. What is the best practice? Is it possible to create a hierarchy of these different object types with a top level schema containing the information below and second level schemas for each type? Or is it better to make a larger schema containing all the information that could be present in all the different types of sources?
"$schema": "http://json-schema.org/schema#",
"title": "Document",
"description": "Information connected to a document",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier",
"type": "number"
},
"name": {
"description": "Title of the source",
"type": "string"
},
"type": {
"description": "Type of source",
"type": "string"
},
"url": {
"description": "URL of the source",
"type": "string"
},
"morePropertiesHere": {
"description": "the rest of the properties vary depending on type of source"
}
},
"required": ["id", "name", "type", "url"]

You can change the properties part in JSON like this, as it takes only number and text.
"properties": {
"id":1234,
"name":"Name of the source",
"description": "Title of the source",
"type": "Type of source",
"url": "URL of the source",
"morePropertiesHere": {
"description": "the rest of the properties vary depending on type of source"
}
}
If Id's are numbers then you can give them as it is instead of putting inside "".

Related

JSON scema question on additionalProperties and required

I ran into this situation recently and would like to check my understanding, with a JSON (draft-7) schema.
additionalProperties is set to false, which means every property in our JSON object MUST be listed in the properties array.
the required array contains category, which is not in the properties array.
{
"$schema": "https://json-schema.org/draft-07/schema#",
"$id": "/my-schema-1.0.0",
"description": "My schema",
"type": "object",
"additionalProperties": false,
"properties": {
"value": {
"description": "The value.",
"type": "number"
}
},
"required": [
"value",
"category"
]
}
However, whenever i try to validate that my schema is valid, multiple validators say that it is.
But then i don't think you can create an object that would ever validate successfully against this schema.
I don't see anything within the JSON spec that mentions this conflict. Is anyone able to shed any light on this?

Reusing JSON subschema

I am needing to use a sub schema multiple times in my JSON file, but haven't been able to figure out the correct way to structure the schema file such that I am able to get the schema validation on all the sub properties instead of just the property that I list in the schema file.
This question here was getting at a similar question, but the answer didn't make much sense/I wasn't sure if or how I could use the same method here. Am I thinking too much in the OOP mindset with multiple instances of a single class?
Here is more or less what I am trying to do
{
"Object1": {
"Title": "Some Title",
"Description": "Some Description"
},
"Object2": {
"Title": "Another title",
"Description": "Another Description"
}
// unknown number of objects but each object should have the same sub schema
}
Here is what I have thus far
{
"$id": "http://example.com/example.json",
"$schema": "http://json-schema.org/draft-07/schema",
"required": [
"Object1"
],
"title": "The root schema",
"type": "object",
"properties": {
"Object1": {
"required": [
"Title",
"Description"
],
"title": "The Reusable Object schema",
"type": "object",
"properties": {
"Title": {
"title": "The Title schema",
"type": "string"
},
"Description": {
"title": "The Description schema",
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": true
}
If all values of the object should follow the schema, the solution is quite simple.
First, you have to remember how additionalProperties works...
The value of "additionalProperties" MUST be a valid JSON Schema.
This keyword determines how child instances validate for objects,
and does not directly validate the immediate instance itself.
Validation with "additionalProperties" applies only to the child
values of instance names that do not match any names in "properties",
and do not match any regular expression in "patternProperties".
For all such properties, validation succeeds if the child instance
validates against the "additionalProperties" schema.
https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-validation-01#section-6.5.6
So, now we know that additionalProperties takes a JSON Schema, and not just booleans (booleans are valid JSON Schema), the solution might be a little obvious.
Remove the outermost additionalPropertie, rename properties to additionalProperties, and remove the key Object1 and object braces.
The result is the following...
...
"title": "The root schema",
"type": "object",
"additionalProperties": {
"required": [
"Title",
"Description"
],
...
Live demo: https://jsonschema.dev/s/pqwCc
I don't know what you would want to do with the outer most required though. I guess remove it, as you don't know in advance what the keys will be.
Maybe you want to use minProperties to make sure there is at least one?

Swagger v2 - Enums association

Unfortunately I could not locate anything relevant in the Swagger v2 documentation or in SO, so I am afraid I have to create this new thread.
What I would like to understand is whether it is feasible to associate enums with each other via Swagger. Consider the scenario where our Definitions specify a "Status" with two enum properties: "Code" and "Description" as per the below excerpt:
"definitions": {
"Status": {
"type": "object",
"properties": {
"Code": {
"type": "string",
"enum": ["01", "02", "03"]
},
"Description": {
"type": "string",
"enum": ["OK", "NOK - Please retry", "NOK - Do not retry"]
}
}
}
}
How could we specify that a given "Code" may only be associated to a specific "Description" (e.g. "01" for "OK", "02" for "NOK - Please retry", etc.)?
Obviously, using a property description (which actually acts as an embedded documentation) is not the way to go when having hundreds of Codes.
Thank you!

Compare object property to validate json schema in same object

I have a very simple object like so:
{
"title": "A registration form",
"description": "A simple form example.",
"type": "object",
"required": [
"firstName",
"lastName"
],
"properties": {
"firstName": {
"type": "string",
"title": "First name"
},
"lastName": {
"type": "string",
"title": "Last name",
"minLength": "{'$ref': '/properties/firstName'}"
},
}
On the property of LastName I would like to compare a value with a value of the property next to it. I am actually comparing integers so in actuality my real world example is even easier, just minimum and maximum.
I looked at the json schema spec here and it seemed like this should be doable, and have tried using relative paths and the $ref object.
Is this not possible?
The reference is here: https://www.rfc-editor.org/rfc/rfc6901
I am using react-jsonschema-form but I don't see where that would effect this.
There are a few of reasons why this doesn't work. The primary reason is that $ref refers to the schema, not the data being validated. There was talk of adding a $data keyword to JSON Schema that would allow referencing the instance data, but I don't think that will even happen.

Is it possible to write a generic JSON Schema?

Inside my root JSON object I have many JSON objects of two different types. I'm wondering if there is a way to write a JSON schema to validate these objects without getting specific, i.e. generic schema.
For example, imagine I have the following JSON:
"Profile":
{
"Name":
{
"Type": "String",
"Value": "Mike",
"Default": "Sarah",
"Description": "This is the name of my person."
}
"Age":
{
"Type": "Number",
"Value": 27,
"Default": 18,
"Description": "This is the age of my person."
}
}
This Profile JSON object represents a collection of various details about a person. Notice I have two different types of inner Objects, String Objects and Number Objects. Taking this into account, I would now like to create a JSON Schema to validate any of the inner objects without being specifc about which Objects they are, e.g. I don't care that we have "Name" or "Age", I care that we have proper String Objects and Number Objects.
Does JSON Schema give me the ability to do this? How do I write a generic JSON Schema based on the kinds of Objects I have and not specific object names?
Here is what I've got so far:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"StringObject": {
"type": "object",
"properties": {
"Type": {
"type": "string"
},
"Value": {
"type": "string"
},
"Default": {
"type": "string"
},
"Description": {
"type": "string"
}
},
"required": [
"Type",
"Value",
"Default",
"Description"
]
}
}
}
Inside my root JSON object I have many JSON objects of two different types. I'm wondering if there is a way to write a JSON schema to validate these objects without getting specific, i.e. generic schema.
Union types are defined to handle this:
A value of the "union" type is encoded as the value of any of the member types.
Union type definition - An array with two or more items which indicates a union of type definitions. Each item in the array may be a simple type definition or a schema.
{
"type":
["string","number"]
}
References
JSON Encoding of Data Modeled with YANG: 6.10. The "union" Type
A JSON Media Type for Describing the Structure and Meaning of JSON Documents: Union Types