i have a personschema which has e.g. those two fields:
"name": {
"title": "Last name",
"type": "string",
"minLength": 1,
"isRequired" : true
}
"birthday": {
"title": "Date of birth",
"$ref": "resource:schema/general/dateSchema.json",
"isRequired" : true
},
"birthCountry": {
"$ref": "resource:schema/general/countrySchema.json",
"title": "Country of birth",
"isRequired" : true
}
Then I have another schema which extends the person schema. In this schema, I want those two properties (birthCountry and birthday) to be optional and only the name to be mandatory. I've tried it like that:
{
"$schema": "http://json-schema.org/draft/2019-09/schema",
"title": "Other Schema",
"type": "object",
"javaType": "..json_schema_model.dto.OtherSchema",
"description": "Other Schema Description",
"extendsJavaClass": "..json_schema_model.dto.PersonSchema",
"allOf": [{
"required": [
"name"
],
"$ref": "resource:schema/general/personSchema.json"
}
But unfortunately, in the API-Docs they are still remarked as mandatory.
The issue was that properties can only be added in child classes and not modified, so I rearranged the class structure to modify the decision whether a value is mandatory will only be decided in the child classes themselves. Also please note, that sibling values alongsid $refs are ignored. To add properties to a $ref, you need to wrap it into an allOf.
Related
I need to add validations for a property as well as a value in json schema.
I tried to use the below schema but none of the validations work :
{
"$schema": "http://json-schema.org/draft-06/schema#",
"type": "object",
"additionalProperties": false,
"minProperties": 1,
"properties": {
"add": {
"type": "object",
"patternProperties": {
"^VOF979[0-9]{11}-NDG[0-9]{2}$": {
"description": "Some description",
"type": "string",
"maxLength": 2
}
}
}
}
}
I used below json data and all the validations passes although the key and value both are wrong :
{
"add": {"VOF98999990005235-NDG01": "121"}
}
JSON Schema is constraints based.
patternProperties applies its value schema to the instance location based on the key match (in this case, regex match).
It does not prohibit additional keys in the object.
If you want to prevent additional keys, you need to specify so.
To do this, you need "additionalProperties": false.
Do not allow additional properties to keep strict validation
{
"$schema": "http://json-schema.org/draft-06/schema#",
"type": "object",
"properties": {
"add": {
"type": "object",
"patternProperties": {
"^VOF979[0-9]{11}-NDG[0-9]{2}$": {
"description": "Some description",
"type": "string",
"maxLength": 2
}
},
"additionalProperties": false // This One
}
},
"additionalProperties": false,
"minProperties": 1
}
Reference to Docs Have a look at this
I am trying to create Body-parameter(JSON) for my POST Api , which is a JSON request . All I have is the JSON Schema . I am trying to come up with a list of different JSON test data covering Positive and negative flows for it .
Is there any option to generate / create the JSON data programmatic using Java ? . I have attached a small Json schema (just for understanding purpose) but my actual schema is more complicated with lot of Array's and Nested Json's .
My Json Schema :
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "http://example.com/example.json",
"type": "object",
"title": "The Root Schema",
"description": "The root schema comprises the entire JSON document.",
"required": [
"FirstName",
"LastName",
"Age",
"Interest"
],
"properties": {
"FirstName": {
"$id": "#/properties/FirstName",
"type": "string",
"title": "The Firstname Schema",
"description": "An explanation about the purpose of this instance.",
"default": "",
"examples": [
"Vijay"
]
},
"LastName": {
"$id": "#/properties/LastName",
"type": "string",
"title": "The Lastname Schema",
"description": "An explanation about the purpose of this instance.",
"default": "",
"examples": [
"Karthik"
]
},
"Age": {
"$id": "#/properties/Age",
"type": "integer",
"title": "The Age Schema",
"description": "An explanation about the purpose of this instance.",
"default": 0,
"examples": [
30
]
},
"Interest": {
"$id": "#/properties/Interest",
"type": "array",
"title": "The Interest Schema",
"description": "An explanation about the purpose of this instance.",
"default": [],
"items": {
"$id": "#/properties/Interest/items",
"type": "string",
"title": "The Items Schema",
"description": "An explanation about the purpose of this instance.",
"default": "",
"examples": [
"Food",
"movie",
"Learning",
"VideoGames"
]
}
}
}
}enter code here
My TestData looks like :
{
"FirstName":"Vivi",
"LastName":"Karrri",
"Age":30,
"Interest":["Food","movie","Learning","VideoGames"]
}
Any suggestions how can we achive this ?
Note : I am using Springboot and I have complete POJO for the request object
You can generate fake java-objects and then map them to JSON.
POJOs
If you already have the POJOs matching the schema, then we can skip this step.
If no, to generate a POJO from the schema, for example, can be used this library:
jsonschema2pojo.
Fake objects
Generating of objects with fake data can be done with a special library, some of them are listed here:
easy-random
podam
java-faker
Generating JSON
It's prettry simple and can be done with Jackson:
ObjectMapper objectMapper = new ObjectMapper();
ObjectWriter prettyPrinter = objectMapper.writerWithDefaultPrettyPrinter();
String json = prettyPrinter.writeValueAsString(yourFakeObject);
If you have json schema then you can directly generate a sample JSON message from it.
https://github.com/jignesh-dhua/json-generator
For example :
i need an Animals table which will contain animal_type as Object or T type as foreign relation field.
then i will have 10 different tables like Dog/Cat/Horse etc.
at the time of insertion based on type of animal i would set animal_type of Animal object.
I don't want to take multiple databaseField for each type as a foreign relation, instead i need one generic field , Using ormlite version 5.0.
please refer this json:{
"animal": {
"type": 1,
"content": {
"items": [
{
"title": "Image",
"desc": "This is item with image",
"media": {
"url": "https://upload.wikimedia.org/wikipedia/commons/9/99/Earth_rise_from_the_Moon_AS11-44-6550_2.JPG",
"type": 0
},
"options": [
{
"title": "View",
"value": "view"
},
{
"title": "Download",
"value": "download"
}
],
"url": "https://commons.wikimedia.org/wiki/File%3AEarth_rise_from_the_Moon_AS11-44-6550_2.JPG"
}
]
}
}
}
I have run into this issue now with implementing arbitrary field behaviour with additionalProperties. Below is my model with additional properties.
"CObject": {
"type": "object",
"properties": {
"_id": {
"type": "string"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"updatedAt": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": {
"type": "string"
}
}
Indeed the only change I see in the generated java client is that my CObject.java now sub-classes HashMap class. I expected that a call to put([key],[value]) on CObject would just add a new property in the request body. On running a test, I realized that all properties within CObject are absent in the final request body. So, the client only sends a request body with properties defined arbitrarily and eliminates all other properties defined in the specification. Am using the latest swagger-codegen(2.1.6 snapshot). how can I get past this issue???
NB I don't want the map values to appear under their own property, I want the key value pairs to appear under the same hierarchy as the rest of the properties defined in the spec.
In the JSON you provided, "additionalProperties" is just a property name and its type is string. Let's say the property name is "keyValuePair", then the correct way to use additionalProperties is
"keyValuePair": {
{
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
I need to serialize JSON to scala case class. It is not a question about JSON serialization, but is a question about class mapping in scala.
The example of JSON:
{
"id": 98433,
"name": "Santa Cruz Bronson",
"vendor": {
"id": 344,
"name": "Santa Cruz"
},
"category": {
"id": 132,
"name": "Bicycles"
},
"annotation": "The best downhill cycle",
"description": "Rich text is here",
"classification": {
"id": 12,
"name": "138-cycles"
},
"properties": [{
"id": 84436,
"group": {
"id": 19433,
"name": "Suspension"
},
"name": "Fork turn",
"description": "Fork turn defines bike suspension",
"value": "129mm"
}, {
"id": 84436,
"group": {
"id": 19433,
"name": "Suspension"
},
"name": "Fork turn",
"description": "Fork turn defines bike suspension",
"value": "129mm"
}, {
"id": 84436,
"group": {
"id": 19433,
"name": "Suspension"
},
"name": "Fork turn",
"description": "Fork turn defines bike suspension",
"value": "129mm"
}, {
"id": 84436,
"group": {
"id": 19433,
"name": "Suspension"
},
"name": "Fork turn",
"description": "Fork turn defines bike suspension",
"value": "129mm"
}],
"isGroup": true
}
I know how to build a case class for top level map:
case class ProductDocument(id: Long, name: String, annotation: String, description: String, isGroup: String) extends DocumentMap {
...
}
But I have no idea how to build values for vendor, category, properties, etc.
I want to define map for this JSON into one class file.
Each of the nested json objects should be defined as their own case classes, such that:
case class Vendor(id: Long, name: String)
case class ProductDocument(id: Long, ..., vendor: Vendor)
The properties would become a List of a Property case class:
case class Property(id: Long, group: PropertyGroup, name: String, description: String, value: String)
case class PropertyGroup(id: Long, name: String)
case class ProductDocument(id: Long, ..., properties: List[Property])
This assumes that you are using json4s serialization.
For scala-json mapping you have at least two options:
Salat - which originally provided ORM-like functionality for Mongo but also works for just JSON serialization (disclaimer: I work at Novus)
json4s - see section "Serialization"
The good news is that because the structure of Scala case classes are well-understood, you generally do not have to define "mapping" between your JSON fields and case class fields. You just write your case classes to match the structure / fields of your JSON document, as Arne Claassen has sketched out.