How to validate dynamic API response (Schema validation) in Postman - arrays

Hello there I have a API that sends dynamic responses and I want to validate the schema of that response.following is the response I am trying to validate.
{
"Data": [
{
"CustomerName": "BeautyProductions",
"Websites": {
"storeone": {
"Keyone":"testvalueone",
"Keytwo":"testvalue two"
}
}
}
]
}
But the thing is the number of websites increases sometimes like following
{
"Data": [
{
"CustomerName": "BeautyProductions",
"Websites": {
"storeone": {
"Keyone":"testvalueone",
"Keytwo":"testvalue two"
},
"storetwo": {
"Keyone":"testvaluestoretwo",
"Keytwo":"testvaluestoretwonow"
}
}
}
]
}
I tried to validate schema as following
var schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"Data": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"CustomerName": {
"type": "string"
},
"Websites": {
"type": "object",
"properties": {
"storeone": {
"type": "object",
"properties": {
"Keyone": {
"type": "string"
},
"Keytwo": {
"type": "string"
}
},
"required": [
"Keyone",
"Keytwo"
]
}
},
"required": [
"storeone"
]
}
},
"required": [
"CustomerName",
"Websites"
]
}
]
}
},
"required": [
"Data"
]
}
var json = pm.response.json()
pm.test('shcema is valid', function(){
pm.expect(tv4.validate(json, schema)).to.be.true;
})
But it fails when the number of website count is increasing. SO, I would liketo know how I can validate this?
Thankyou

I don't know if the "stored" field is required, but you can use the "additionalProperties". The "additionalProperties" field allows you to specify a schema for properties in the object that are not explicitly defined in the properties field.
Please try below schema if it works:
var schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"Data": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"CustomerName": {
"type": "string"
},
"Websites": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"Keyone": {
"type": "string"
},
"Keytwo": {
"type": "string"
}
},
"required": [
"Keyone",
"Keytwo"
]
}
}
},
"required": [
"CustomerName",
"Websites"
]
}
]
}
},
"required": [
"Data"
]
}

Related

How to create array json schema for an array string which contains some fixed values and may have other additonal values

So I have this json schema:-
{
"type": "object",
"properties": {
"campaignType": {
"type": "string",
"enum": [
"export"
]
},
"clientid": {
"type": "integer",
"minimum": 1
},
"select": {
"type": "object",
"minProperties": 1,
"anyOf": [
{
"required": [
"list"
]
},
{
"required": [
"segment"
]
}
],
"properties": {
"list": {
"type": "array",
"items": {
"type": "integer"
}
},
"segment": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"attributes": {
"type": "array",
"minItems": 2,
"items": {
"type": "string",
"contains": ["fk", "uid"]
}
}
},
"required": [
"campaignType",
"clientid",
"select",
"attributes"
]
}
Here I want to have attributes field to have value "fk", "uid" fixed and must allow other field values with "fk" and "uid".
with this following code I am getting error while passing additonal values:-
{
"campaignType":"export",
"clientid":107311,
"select":{
"segment":[30]
},
"attributes":["uid","fk", "att1"]
}
error unmarshaling properties from json: error unmarshaling items from json: json: cannot unmarshal object into Go value of type []*jsonschema.Schema
how do I fix it?
The value of contains in your schema must be a schema:
According to your question, maybe change the "attributes" schema to:
"attributes": {
"type": "array",
"minItems": 2,
"items": [ { "const": "fk" }, { "const": "uid" } ],
"additionalItems": {
"type": "string"
}
}

JSON-schema object array validation

I have a mission to validate such a JSON message :
{
"header": {
"action": "change_time",
"taskGuid": "someTaskGuid",
"publishDate": "2012-04-23T18:25:43.511Z"
},
"data": {
"code": "f2103839",
"conditions": [
{
"conditionsType": "A",
"dateBegin": "2021-11-22T17:30:43.511Z",
"dateEnd": "2021-11-22T17:35:43.511Z"
},
{
"conditionsType": "B",
"dateBegin": "2021-11-22T17:30:43.511Z",
"dateEnd": "2021-11-22T17:35:43.511Z"
},
{
"conditionsType": "C",
"dateBegin": "2021-11-22T17:30:43.511Z",
"dateEnd": "2021-11-22T17:35:43.511Z"
}
]
}
}
I've made such a JSON-schema to achieve that :
{
"$schema": "http://json-schema.org/draft-07/schema",
"title": "Some schema",
"description": "Some schema",
"type": "object",
"required": [
"header",
"data"
],
"properties": {
"header": {
"type": "object",
"required": [
"action",
"taskGuid",
"publishDate"
],
"properties": {
"action": {
"enum": [
"create_work_order",
"change_time",
"cancel_work"
]
},
"taskGuid": {
"type": "string"
},
"publishDate": {
"type": "string",
"format": "date-time"
}
}
},
"data": {
"type": "object",
"required": [
"code",
"conditions"
],
"properties": {
"code": {
"type": "string"
},
"conditions": {
"type": "array",
"items": [
{
"conditionsType": "object",
"properties": {
"type": {
"enum": [
"A",
"B",
"C"
]
},
"dateBegin": {
"type": "string",
"format": "date-time"
},
"dateEnd": {
"type": "string",
"format": "date-time"
}
},
"required": [
"conditionsType",
"dateBegin",
"dateEnd"
]
}
]
}
}
}
}
}
The conditions array will consist of 1-3 objects described by items. Each object should have a unique conditionsType.
I'm checking validation with this instrument - https://www.jsonschemavalidator.net/
The problem is that this schema does validate the message, But only the first object of array is processed as de. For instance, such a JSON is validated as well (see "conditions" object #2):
{
"header": {
"action": "change_time",
"taskGuid": "someTaskGuid",
"publishDate": "2012-04-23T18:25:43.511Z"
},
"data": {
"code": "f2103839",
"conditions": [
{
"conditionsType": "A",
"dateBegin": "2021-11-22T17:30:43.511Z",
"dateEnd": "2021-11-22T17:35:43.511Z"
},
{
"conditionsType": 123,
"dateBegin": [1,2,3],
"dateEnd": 1
},
{
"conditionsType": "C",
"dateBegin": "2021-11-22T17:30:43.511Z",
"dateEnd": "2021-11-22T17:35:43.511Z"
}
]
}
}
Is that actually the right direction I've chosen for this task ?
Two things. You have a typo in your items schema where you actually want to have type and not conditionsType. Secondly, if the items keyword is an array, the items of the array are validated against the schemas in this order. You want to have the items keyword as a single schema which is then applied to all items. Your corrected schema for copy-paste:
{"$schema":"http://json-schema.org/draft-07/schema","title":"Some schema","description":"Some schema","type":"object","required":["header","data"],"properties":{"header":{"type":"object","required":["action","taskGuid","publishDate"],"properties":{"action":{"enum":["create_work_order","change_time","cancel_work"]},"taskGuid":{"type":"string"},"publishDate":{"type":"string","format":"date-time"}}},"data":{"type":"object","required":["code","conditions"],"properties":{"code":{"type":"string"},"conditions":{"type":"array","items":{"type":"object","properties":{"conditionsType":{"enum":["A","B","C"]},"dateBegin":{"type":"string","format":"date-time"},"dateEnd":{"type":"string","format":"date-time"}},"required":["conditionsType","dateBegin","dateEnd"]}}}}}}

Unable to validate complete JSON schema using tv4

Total newb here.
I'm wondering if someone can help because i'm at a loss! I'm trying to assert that the response from a GET API Call meets this monster schema set - Using console.log() it looks like each of the properties is accessed successfully and if i change the object type the test will fail as i'd expect.
Working down the schema - If i try and change a property in the data array i.e from string to boolean the test will still pass although it doesn't meet the required schema i've defined,
Any guidance is massively appreciated!
//Test the schema is valid
const schema = {
"type": "object",
"properties": {
"current_page": {
"type": "integer"
},
"data": {
"type": "array",
"properties": {
"id": {
"type": "integer"
},
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
},
"telephone": {
"type": "string"
},
"postcode": {
"type": "string"
},
"date_of_birth": {
"type": "string"
},
"profession": {
"type": "string"
},
"time_served": {
"type": "integer"
},
"national_insurance_number": {
"type": "string"
},
"employer": {
"type": "string"
},
"lco_id": {
"type": "integer"
},
"company_employed": {
"type": "null"
},
"company_employed_email": {
"type": "null"
},
"company_employed_telephone": {
"type": "string"
},
"company_employed_address": {
"type": "null"
},
"apprentice": {
"type": "boolean"
},
"apprentice_trade": {
"type": "string"
},
"apprentice_course": {
"type": "string"
},
"apprentice_started_at": {
"type": "string"
},
"apprentice_ended_at": {
"type": "string"
},
"work_experience": {
"type": "boolean"
},
"work_experience_trade": {
"type": "null"
},
"work_experience_education": {
"type": "null"
},
"work_experience_started_at": {
"type": "null"
},
"work_experience_ended_at": {
"type": "null"
},
"nvq": {
"type": "boolean"
},
"nvq_trade": {
"type": "string"
},
"nvq_education": {
"type": "string"
},
"nvq_started_at": {
"type": "string"
},
"nvq_ended_at": {
"type": "string"
},
"unemployed": {
"type": "boolean"
},
"unemployed_months": {
"type": "null"
},
"company_employed_postcode": {
"type": "string"
},
"partner_relationship": {
"type": "null"
},
"self_partner_relationship": {
"type": "null"
},
"emergency_contact_first_name": {
"type": "string"
},
"emergency_contact_last_name": {
"type": "string"
},
"emergency_contact_telephone": {
"type": "string"
},
"enrollment_id": {
"type": "integer"
},
"created_at": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"mode_of_travel": {
"type": "string"
},
"driver_or_passenger": {
"type": "string"
},
"fuel_type": {
"type": "string"
},
"engine_capacity": {
"type": "string"
},
"rtw_declaration": {
"type": "boolean"
},
"rtw_proof1_upload_id": {
"type": "null"
},
"rtw_proof2_upload_id": {
"type": "null"
},
"card_type": {
"type": "string"
},
"gender": {
"type": "string"
},
"self_gender": {
"type": "null"
},
"marital_status": {
"type": "string"
},
"disability_act": {
"type": "string"
},
"disability_description": {
"type": "null"
},
"ethnic_origin": {
"type": "string"
},
"religion": {
"type": "string"
},
"nationality": {
"type": "string"
},
"sexual_orient": {
"type": "string"
},
"checked_membership": {
"type": "integer"
},
"training_checked": {
"type": "integer"
},
"enrollment": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"inducted": {
"type": "boolean"
},
"user_id": {
"type": "integer"
},
"created_at": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"expiry_date": {
"type": "string"
},
"user": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"email": {
"type": "string"
},
"role": {
"type": "integer"
},
"created_at": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"state": {
"type": "integer"
},
"last_login_at": {
"type": "null"
}
},
"required": [
"id",
"email",
"role",
"created_at",
"updated_at",
"state",
"last_login_at"
]
}
},
"required": [
"id",
"inducted",
"user_id",
"created_at",
"updated_at",
"expiry_date",
"user"
]
}
},
"required": [
"id",
"first_name",
"last_name",
"telephone",
"postcode",
"date_of_birth",
"profession",
"time_served",
"national_insurance_number",
"employer",
"lco_id",
"company_employed",
"company_employed_email",
"company_employed_telephone",
"company_employed_address",
"apprentice",
"apprentice_trade",
"apprentice_course",
"apprentice_started_at",
"apprentice_ended_at",
"work_experience",
"work_experience_trade",
"work_experience_education",
"work_experience_started_at",
"work_experience_ended_at",
"nvq",
"nvq_trade",
"nvq_education",
"nvq_started_at",
"nvq_ended_at",
"unemployed",
"unemployed_months",
"company_employed_postcode",
"partner_relationship",
"self_partner_relationship",
"emergency_contact_first_name",
"emergency_contact_last_name",
"emergency_contact_telephone",
"enrollment_id",
"created_at",
"updated_at",
"mode_of_travel",
"driver_or_passenger",
"fuel_type",
"engine_capacity",
"rtw_declaration",
"rtw_proof1_upload_id",
"rtw_proof2_upload_id",
"card_type",
"gender",
"self_gender",
"marital_status",
"disability_act",
"disability_description",
"ethnic_origin",
"religion",
"nationality",
"sexual_orient",
"checked_membership",
"training_checked",
"enrollment",
]
},
}
}
// Use tiny validator to validate the results - Error if there are additional properties, and check recursion.
pm.test("Validate schema contains the relevant details", () => {
tv4.validateMultiple(jsonData, schema, true, true);
var jsonData = JSON.parse(responseBody);
// Log all errors to the console
var validationResult = tv4.validateMultiple(jsonData, schema, true, true);
for (var i = 0; i < validationResult.errors.length; i++) {
console.log("path :" + validationResult.errors[i].dataPath + " message :" + validationResult.errors[i].message);
}
});
const schema = {
"type": "object",
"properties": {
"current_page": {
"type": "boolean"
}
}
}
pm.test("Validate schema contains the relevant details", () => {
var jsonData = { "current_page": 2 }
// Log all errors to the console
var validationResult = tv4.validateMultiple(jsonData, schema, true, true);
validationResult.valid ? null : console.log(JSON.stringify(validationResult, null, 2))
pm.expect(validationResult.valid, JSON.stringify(validationResult, null, 2)).to.be.true
});
you don't have expect to assert it that's why it passes always , also as Danny mentioned use
const schema = {
"type": "object",
"properties": {
"current_page": {
"type": "boolean"
}
}
}
pm.test("Validate schema contains the relevant details", () => {
var jsonData = { "current_page": 2 }
pm.response.to.have.jsonSchema(schema)
});
And for array you should use items instead of property:
const schema = {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"required":["id","name"]
}
}
}
}
pm.test("Validate schema contains the relevant details", () => {
var jsonData = { "data": [{ "id": 2,"name":"test" }] }
// Log all errors to the console
var validationResult = tv4.validateMultiple(jsonData, schema, true, true);
validationResult.valid ? null : console.log(JSON.stringify(validationResult, null, 2))
pm.expect(validationResult.valid, JSON.stringify(validationResult, null, 2)).to.be.true
});
you can create schema with so much ease using :
https://www.jsonschema.net/login

Azure Logic App Partition key [X] is invalid with COsmos Db

I need to save JSON parsed data to Cosmos Db, HTTP trigger works as it should as well as parsing but getting Partition key [my_dynamic_key_value] is invalid.
Did anyone have a similar issue?
I have found this article link but still getting the same error.
Thanks
EDIT 1
This is the flow for adding item to DB
Schema:
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"Groups": {
"type": "array",
"items": {
"type": "string"
}
},
"JobName": {
"type": "string"
},
"Link": {
"type": "string"
},
"MinSalary": {
"type": "string"
},
"MaxSalary": {
"type": "string"
},
"Hours": {
"type": "string"
},
"WorkPattern": {
"type": "string"
},
"Details": {
"type": "array",
"items": {
"type": "object",
"properties": {
"Name": {
"type": "string"
},
"Detail": {
"type": "string"
}
},
"required": [
"Name",
"Detail"
]
}
}
},
"required": [
"id",
"Groups",
"JobName",
"Link",
"MinSalary",
"MaxSalary",
"Hours",
"WorkPattern",
"Details"
]
}
}
Here is a response:
{
"code": "BadRequest",
"message": "Partition key [1bb2d44f-a066-4fa8-8a78-0cdcea1a756c] is invalid.\r\nActivityId: 345f9a99-534b-40cb-9dc0-9863dc8c90f5, \r\nRequestStartTime: 2020-04-28T08:04:46.8249255Z, RequestEndTime: 2020-04-28T08:04:46.8249255Z, Number of regions attempted:1\r\n, Microsoft.Azure.Documents.Common/2.10.0"
}
You need to set the partition key in the double quotes. Refer to sample screen shot below

json schema - Parent array(array of object) items have an inner array (array of primitive) with given values

Please feel free to update fitting title for this question.
I am trying to achieve something like this. An input JSON/data JSON must have an OWNER and a CHARGE_TO Account, but these don't have to be on the same Account (I.e. one Account can be OWNER, another can be CHARGE_TO) and must not contain account with any other roles.
NOTE: Need to define JSON schema which should be simple to maintain. i.e. Should be easy to add a new role in the condition. My valid and invalid JSONs are,
*************************** VALID JSON1 *********************************
{
"user": [
{
"name": "user1",
"roles": ["OWNER"]
},
{
"name": "user2",
"roles": ["ANY_OTHER_ROLE"]
},
{
"name": "user3",
"roles": ["CHARGE_TO"]
}]
}
*************************** VALID JSON2 *********************************
{
"user": [
{
"name": "user1",
"roles": ["OWNER", "CHARGE_TO"]
},
{
"name": "user2",
"roles": ["ANY_OTHER_ROLE"]
}]
}
*************************** INVALID JSON *********************************
{
"user": [
{
"name": "user1",
"roles": ["OWNER"]
},
{
"name": "user2",
"roles": ["ANY_OTHER_ROLE"]
}]
}
A JSON is valid if it has a user with roles ("OWNER" & "CHARGE_TO") or if users with roles (user1 - "OWNER", user3-"CHARGE_TO", other users with any other role).
Below is JSON schema I tried (draft_07). THIS IS NOT A WORKING SCHEMA.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Complex inner array",
"type": "object",
"properties": {
"user": {
"type": "array",
"contains": {
"type": "object",
"properties": {
"name": { "type": "string" },
"orderRoles": {
"type": "array",
"minItems": 1,
"items": { "type": "string" }
}
},
"oneOf": [
{ "properties": { "roles": { "enum": ["OWNER", "CHARGE_TO"] }}},
{ "properties": { "roles": { "enum": ["OWNER"] }}},
{ "properties": { "roles": { "enum": ["CHARGE_TO"] }}}
]
},
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"orderRoles": {
"type": "array",
"minItems": 1,
"items": { "type": "string" }
}
}
}
}
}
}
Below is my working schema. This is not an elegant solution as schema becomes huge if a new role ("ADMIN") is added, i.e. schema condition would An input JSON/data JSON must have an OWNER, ADMIN and a CHARGE_TO Account, but these don't have to be on the same Account (I.e. one Account can be OWNER, one Account can be ADMIN & another can be CHARGE_TO) and must not contain account with any other roles. Please feel free to improve this. Thanks.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Complex inner array",
"type": "object",
"allOf": [
{
"properties": {
"account": {
"type": "array",
"contains": {
"type": "object",
"properties": {
"roles": {
"type": "array",
"minItems": 1,
"contains": { "enum": ["OWNER"] }
}
}
}
}
}
},
{
"properties": {
"account": {
"type": "array",
"contains": {
"type": "object",
"properties": {
"roles": {
"type": "array",
"minItems": 1,
"contains": { "enum": ["CHARGE_TO"] }
}
}
}
}
}
},
{
"properties": {
"account": {
"type": "array",
"items": {
"type": "object",
"properties": {
"roles": {
"type": "array",
"minItems": 1,
"items":{
"enum": ["CHARGE_TO", "OWNER"]
}
}
}
}
}
}
}
]
}
You need to isolate the part of the schema that checks for a specific role. Then you can just combine them with allOf. There's as little duplication as possible and you can easily add another constraint.
{
"type": "object",
"properties": {
"user": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"roles": {
"type": "array",
"items": { "type": "string" }
}
}
},
"allOf": [
{ "$ref": "#/definitions/require-role-owner" },
{ "$ref": "#/definitions/require-role-charge-to" }
]
}
},
"definitions": {
"require-role-owner": {
"contains": {
"properties": {
"roles": {
"contains": { "const": "OWNER" },
"allOf": [{ "$ref": "#/definitions/not-other-role" }]
}
}
}
},
"require-role-charge-to": {
"contains": {
"properties": {
"roles": {
"contains": { "const": "CHARGE_TO" },
"allOf": [{ "$ref": "#/definitions/not-other-role" }]
}
}
}
},
"not-other-role": {
"items": { "enum": ["OWNER", "CHARGE_TO"] }
}
}
}

Resources