JSON schema - support regular expression for field - json

I want to use the following library gojsonschema to validate json structure,
Currenlty I've two questions to the example below
https://github.com/xeipuuv/gojsonschema
what is the #/definitions/.... and what is the purpose of it?
the name should have the following:
{required: true, unique: true, pattern: '/^[A-Za-z0-9_\-\.]+$/'}
The unique is that if I've another name filed in the schema it should be unique, How can I validate it with jsonschema?
var schema = `
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"name": ...
"properties": {
"username": {"$ref": "#/definitions/name"},
update
what I found is this
https://spacetelescope.github.io/understanding-json-schema/reference/regular_expressions.html
But how should I check it inside the json i've provided
should It be like this
var schema = `
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"name": {
"type": "object",
"pattern":'/^[A-Za-z0-9_\-\.]+$/'
}
"properties": {
"username": {"$ref": "#/definitions/name"},

https://datatracker.ietf.org/doc/draft-handrews-json-schema-validation/?include_text=1
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"username": {
"type": "array",
"items": {
"type": "string",
"pattern": "/^[A-Za-z0-9_\-\.]+$/"
},
"uniqueItems": true
}
},
"required": [
"username"
]
}
1: The "definitions" keywords provides a standardized location for
schema authors to inline re-usable JSON Schemas into a more general
schema. The keyword does not directly affect the validation result.
This keyword's value MUST be an object. Each member value of this
object MUST be a valid JSON Schema.
As an example, here is a schema describing an array of positive
integers, where the positive integer constraint is a subschema in
"definitions":
{
"type": "array",
"items": { "$ref": "#/definitions/positiveInteger" },
"definitions": {
"positiveInteger": {
"type": "integer",
"exclusiveMinimum": 0
}
}
}
2: uniqueItems
The value of this keyword MUST be a boolean.
If this keyword has boolean value false, the instance validates
successfully. If it has boolean value true, the instance validates
successfully if all of its elements are unique.
Omitting this keyword has the same behavior as a value of false.
required
The value of this keyword MUST be an array. Elements of this array,
if any, MUST be strings, and MUST be unique.
An object instance is valid against this keyword if every item in the
array is the name of a property in the instance.
Omitting this keyword has the same behavior as an empty array.
properties
{
"type": "object",
"properties": {
"progBinaryName": {
"type": "string",
"pattern": "^[A-Za-z0-9 -_]+_Prog\\.(exe|EXE)$"
}
}
}
The value of "properties" MUST be an object. Each value of this
object 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 succeeds if, for each name that appears in both the
instance and as a name within this keyword's value, the child
instance for that name successfully validates against the
corresponding schema.
Omitting this keyword has the same behavior as an empty object.

#/definitions/name is an internal reference to another schema. The document should have section that looks like the following that is being referenced:
"definitions": {
"name": {
...
}
}
JSON schema does not have a unique validator. There is a uniqueItems validator that can be used with arrays but I don't think that is what you are looking for.

Related

Is there a Json schema validation implementation give all the missing required fields?

Normally, when validate a complicated json object, if an embedded field is required but the parent which is also required is missing, a validator only give the result saying the parent is required.
Wondering if there is a way (an implementation of json schema validator) to find all the mandatory fields (in the leaves of a json object) by applying a json schema validation?
Using https://www.jsonschemavalidator.net/
With schema
{
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "object",
"required": [
"firstName",
"secondName"
],
"properties": {
"firstName": {
"type": "string"
},
"secondName": {
"type": "string"
}
}
}
}
}
To validate an empty json object {}.
Can only get one error Message:
Required properties are missing from object: name.
Schema path: #/required
Can a validator give all the required fields including first and second names back in the error message?

Json Schema - validate pattern for string inside an array is ignored

I have a schema defined this way:
"permissions": {
"type": "array",
"properties": {
"items":
{
"$ref": "#/definitions/permissionsType"
}
}
},
and permissionsType:
"permissionsType": {
"type": "string",
"pattern": "^[a-zA-Z0-9]+(:[a-zA-Z0-9][a-zA-Z0-9-]+)+$"
},
...
I am not sure why the pattern regex is ignored.
Remove the properties keyword and it will work as expected.
I'm not sure what you're trying to do with the properties keyword here. properties only applies when the instance being validated is an object. Because the instance is an array, properties is ignored. If the instance were an object, the properties keyword would apply, but it would be expecting an object with a property name "items" that matches #/definitions/permissionsType. I don't think that's what you meant. I think you wanted an array whose items all match #/definitions/permissionsType.
"permissions": {
"type": "array",
"items": { "$ref": "#/definitions/permissionsType" }
}

Apply required field to referenced JSON data schema

I have the following use-case I try to solve with JSON schemas.
I have a generic JSON data schema for, for example, a user. Here is an example of the user.schema.json file.
{
"type": "object",
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"email": {
"type": "string",
"minLength": 1
},
"locale": {
"type": "string",
"minLength": 1
},
"active": {
"type": "boolean",
"default": true
},
"password": {
"type": "string",
"minLength": 8
},
"roles": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
}
}
}
Now I have 2 different kinds of requests:
- POST: Add a user
- PATCH: Update user data.
In 1 case, I can send this data structure, with 3 required fields, while in case of a patch each field is optional.
So I get the post request file: post-user.schema.json:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "user.schema.json",
"required": [
"name",
"password",
"email"
]
}
And for my patch (path-user.schema.json:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "user.schema.json"
}
Now the issue that I am having is that my POST schema also marks a user like:
{
"name": "NoPassword",
"email": "nopassword#moba.nl",
"roles": []
}
Which is missing the required password field, as a valid JSON schema.
Apparently, this is not the way to assign required fields to a referenced data structure. I have tried to use google to see what I can find on the subject regarding this using searches like:
[ how to assign required field to referenced schema's ]
and I tried to obtain this info from the documentation.
I have no luck.
My questions now are:
A. Is it possible to assign required fields to a $referenced json schema data object.
B. If this is possible how to do it
C. If this is not possible, what would be a good way to approach this.
Any help is much appreciated.
Using $ref results in all other properties in the object being ignored, so you need to wrap your use of $ref.
Let's take a look at the spec:
An object schema with a "$ref" property MUST be interpreted as a
"$ref" reference. The value of the "$ref" property MUST be a URI
Reference. Resolved against the current URI base, it identifies the
URI of a schema to use. All other properties in a "$ref" object MUST
be ignored.
https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-01#section-8.3
Then consider the schema you included in your question:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "user.schema.json",
"required": [
"name",
"password",
"email"
]
}
Reading the spec, you can see why required will be ignored.
Originally $ref was only designed to replace a WHOLE object, not ADD to the conditions for the object.
What you want is for multiple schemas to be applied to the instance. To do this, you use allOf.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"allOf": [
{
"$ref": "user.schema.json"
},
{
"required": [
"name",
"password",
"email"
]
}
]
}
I loaded this schema into a demo for you to test at https://jsonschema.dev - although it doesn't support references yet, so I transcluded the reference, but the validation will work the same.
From draft-8 onwards, $ref will behave as you expect, as it becomes an applicator keyword rather than a keyword with special behaviours, meaning other keywords in the same object will not need to be ignored.

How to validate for nullable types using json schema validator?

I'm using the play-json-schema-validator and want to set up an integration test with scala in order to check an API's JSON response schema.
Certain fields of the response are nullable and I want to validate for that. So some field can be either a string or null yet it can never be a number.
Playing around on its playground I want to validate for an array of objects that each object's name property is either a string or null.
I came up with this schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product set",
"type": "array",
"items": {
"title": "Product",
"type": "object",
"properties": {
"name": {
"type": ["string", null]
}
}
}
}
Yet though it validates the string and null case, I now get a false positive for numbers. I was expecting an error for this json, yet it validates:
[
{
"name": "Red anger"
},
{
"name": null
},
{
"name": 13
}
]
How to declare a field of a type as nullable using schema validator?
Enquote the null in the schema:
"type": ["string", "null"]
You can read about that in the json schema validation documentation, i.e.:
6.1. Validation Keywords for Any Instance Type
6.1.1. type
The value of this keyword MUST be either a string or an array. If it is an array, elements of the array MUST be strings and
MUST be unique.
String values MUST be one of the six primitive types ("null",
"boolean", "object", "array", "number", or "string"), or "integer"
which matches any number with a zero fractional part.
An instance validates if and only if the instance is in any of the
sets listed for this keyword.
The type attribute of the schema does not accept arrays but only a single type at the time:
"string", "null"... and as you pointed out, the types should be strings so instead of null => "null"
If you want to check multiple types for a single field you need to use
anyOf, oneOf, allOf
Here is an example working with your input
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product set",
"type": "array",
"items": {
"title": "Product",
"type": "object",
"properties": {
"name": {
"anyOf": [
{"type":"string"},
{"type":"null"},
{"type":"number"}
]
}
}
}
}

How would you design JSON Schema for an arbitrary key?

I have the following JSON output data:
{
"label_name_0" : 0,
"label_name_5" : 3,
.
.
.
"label_name_XXX" : 4
}
The output is simple: a key[1] name associated with integer value. If the key name doesn't change, I can easily come up with JSON Schema similar to this:
{
"type": "array"
"title": "Data output",
"items" :{
"properties": {
"label_name": {
"type": "integer",
"default": 0,
"readonly": True,
}
}
},
Since the key name itself is not known and keep changing, I have to design schema for it. The only thing I know is that the key is string and not more than 100 characters. How do I define a JSON Schema for the key lable_name_xxx that keeps changing.
[1] Not sure if I am using the right terminology
On json-schema.org you will find something appropriate in the File System Example section. You can define patternProperties inside an object.
{
"type": "object",
"properties": {
"/": {}
},
"patternProperties": {
"^(label_name_[0-9]+)+$": { "type": "integer" }
},
"additionalProperties": false,
}
The regular expression (label_name_[0-9]+)+ should fit your needs. In JSON Schema regular expressions are explicitly anchored with ^ and $. The regular expressions defines, that there has to be at least one property (+). The property consists of label_name_ and a number between 0 and 9 whereas there has to be at least one number ([0-9]+), but there can also arbitrary many of them.
By setting additionalProperties to false it constrains object properties to match the regular expression.
As Konrad's answer stated, use patternProperties. But use in place of properties, which is not needed, and I think Konrad just pasted from his reference example that was expecting a path starting with /. In the example below, the pattern match regex .* accepts any property name and I am allowing types of string or null only by using "additionalProperties": false.
"patternProperties": {
"^.*$": {
"anyOf": [
{"type": "string"},
{"type": "null"}
]
}
},
"additionalProperties": false
Simpler solution than patternProperties, since OP does not have any requirement on the key names (documentation):
{
"type": "object",
"additionalProperties": {
"type": "integer",
"default": 0,
"readonly": true,
}
}
default and readonly included because they were included in the OP's initial suggestion, but they are not required.