Languages
[Edit]
EN

JavaScript - simple own json schema

9 points
Created by:
JustMike
27910

In this short article we would like to show how in JavaScript write simple logic to manage simple JSON schema.

The article contains three parts:

  1. example schmeas,
  2. simple logic that let us to fill empty properies in some object to unify object with schema,
  3. simple logic that let us to validate object according to schema.

Example schemas

Below array contains simple usage cases only, but it is verry easy to understand the template. The main idea of the schema is to use type property to describe JSON part type: boolean, number, string, array or object.

Simple object:

Example schemnaExample JSON
const schema = {
  type: 'object',
  properties: [
    {name: 'name', type: 'string'},
    {name: 'age',  type: 'number'},
  ]
}
{name: 'John', age: 26}





Simple array:

Example schemnaExample JSON
const schema = {
  type: 'array',
  item: {
    // without name because array items don't have names
    type: 'string'
    // or:
    //   type: 'number'
    // or:
    //   type: 'boolean'
    // or:
    //   type: 'object', properties: []
    // or:
    //   type: 'array',  item: {}
  }
}
['a', 'b', 'c']













Nested object:

Example schemnaExample JSON
const schema = {
  type: 'object',
  properties: [
    {name: 'name', type: 'string'},
    {name: 'age',  type: 'number'},
    {
      name: 'address',
      type: 'object', // type: 'object' requires to provide object properties
      properties: [
        {name: 'country',  type: 'string'},
        {name: 'city',     type: 'string'},
        {name: 'postcode', type: 'string'},
        {name: 'street',   type: 'string'},
        {name: 'number',   type: 'string'}
      ]
    }
  ]
}
{
  name: 'John',
  age: 26,
  address: {
    country: 'UK',
    city: 'London',
    postcode: '000 000',
    street: null,
    number: null
  }
}






Nested array:

Example schemnaExample JSON
const schema = {
  type: 'object',
  properties: [
    {name: 'name', type: 'string'},
    {name: 'age',  type: 'number'},
    {
      name: 'tasks',
      type: 'array', // type: 'array' requires to provide JSON array item definition
      item: {
        // without name because array items don't have names
        type: 'string'
        // or:
        //   type: 'number'
        // or:
        //   type: 'boolean'
        // or:
        //   type: 'object', properties: []
        // or:
        //   type: 'array',  item: {}
      }
    }
  ]
}
{
  name: 'John',
  age: 26,
  tasks: ['a', 'b', 'c']
}


















Filling missing properties example

In this section we would like to show how to write simple logic that let us to fill a object with null properties if some fields defined in JSON Schema were not defined in the object that we want to unify. 

// ONLINE-RUNNER:browser;

const createValue = (schema, initialValue) => {
    if (schema.type === 'object') {
        return createObject(schema.properties, initialValue);
    }
    if (schema.type === 'array') {
        return createArray(schema.item, initialValue);
    }
    return initialValue ?? null;
};

const createObject = (schema, initialObject) => {
    const data = {};
  	if (schema) {
        for (const entry of schema) {
            data[entry.name] = createValue(entry, initialObject?.[entry.name]);
        }
    }
    return data;
};

const createArray = (schema, initialArray) => {
    const data = [];
  	if (initialArray) {
        for (let i = 0; i < initialArray.length; ++i) {
            data.push(createValue(schema, initialArray[i]));
        }
    }
    return data;
};

const createData = (schema, initialData) => {
  	return createValue(schema, initialData);
};

// Usage example:

const schema = {
    type: 'object',
    properties: [
        {name: 'name', type: 'string'},
        {name: 'age',  type: 'number'},
        {
            name: 'tasks',
            type: 'array',
            item: {
                type: 'string'
            }
        },
        {
            name: 'address',
            type: 'object',
            properties: [
              	{name: 'country',  type: 'string'},
              	{name: 'city',     type: 'string'},
              	{name: 'postcode', type: 'string'},
              	{name: 'street',   type: 'string'},
              	{name: 'number',   type: 'string'}
            ]
        }
    ]
};

const data1 = {}; // this object will be filled with missing poprerties
const data2 = {
	name: 'John',
  	// age property will be added
  	tasks: ['do shopping', 'find job', 'go to gym'],
  	address: {
    	country: 'UK',
      	city: 'London',
      	// postcode property will be added
        // street property will be added
        // number property will be added
    }
};

console.log(JSON.stringify(createData(schema, data1), null, 5));
console.log(JSON.stringify(createData(schema, data2), null, 5));

Simple JSON Schema validator example

This section contains example JSON Schema validation logic.

// ONLINE-RUNNER:browser;

const validateValue = (schema, value) => {
    if (schema.type === 'object') {
        return validateObject(schema.properties, value);
    }
    if (schema.type === 'array') {
        return validateArray(schema.item, value);
    }
	return (schema.type === typeof value); // e.g. boolean, string, number
};

const validateObject = (schema, object) => {
  	if (schema) {
      	if (object === undefined || object === null) {
        	return false;
        }
        for (const entry of schema) {
            if (!validateValue(entry, object[entry.name])) {
            	return false;
            }
        }
    }
    return true;
};

const validateArray = (schema, array) => {
  	if (array) {
      	if (schema === undefined || schema == null) {
        	return false;
        }
        for (let i = 0; i < array.length; ++i) {
            if (!validateValue(schema, array[i])) {
            	return false;
            }
        }
    }
    return true;
};

const validateData = (schema, data) => {
  	return validateValue(schema, data);
};

// Usage example:

const schema = {
    type: 'object',
    properties: [
        {name: 'name', type: 'string'},
        {name: 'age',  type: 'number'},
        {
            name: 'tasks',
            type: 'array',
            item: {
                type: 'string'
            }
        },
        {
            name: 'address',
            type: 'object',
            properties: [
              	{name: 'country',  type: 'string'},
              	{name: 'city',     type: 'string'},
              	{name: 'postcode', type: 'string'},
              	{name: 'street',   type: 'string'},
              	{name: 'number',   type: 'string'}
            ]
        }
    ]
};

const data1 = {}; // not valid schema - all properties undefined

const data2 = { // not valid schema - some properties undefined
	name: 'John',
  	// age property undefined
  	tasks: ['do shopping', 'find job', 'go to gym'],
  	address: {
    	country: 'UK',
      	city: 'London',
      	// postcode property undefined
        // street property undefined
        // number property undefined
    }
};

const data3 = { // valid schema
	name: 'John',
  	age: 26,
  	tasks: ['do shopping', 'find job', 'go to gym'],
  	address: {
    	country: 'UK',
      	city: 'London',
      	postcode: 'SW1A 0AA',
        street: 'Great George St.',
        number: '44a'
    }
};

console.log(validateData(schema, data1)); // false
console.log(validateData(schema, data2)); // false
console.log(validateData(schema, data3)); // true
Native Advertising
­čÜÇ
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

ÔŁĄ´ŞĆ­čĺ╗ ­čÖé

Join