Efficiently validate nested JSON schema/config on front end

Viewed 1132

I have following JSON config in a typescript project. I would like to validate this on the front-end during run-time. I am looking for a solution similar to node-convict.

I need to validate

  1. unique id / No duplicate Id.
  2. unique name.
  3. required property non empty type
  4. Multiple children types conditionally e.g. if type === folder they should have children prop. it can be an empty array.
  5. Nested Objects at multiple levels.

I've found AJV. AJV docs only refer to whole object being unique not specific properties. I could potentially come up with my own and do some recursive validation. However, I am looking for most efficient solution whether using ajv, another library or an efficient data structure that I could use to validate this.

If using external library it need to be compatible with typescript. I am NOT looking for typescript compile-time validation.

[{
    "type": "folder",
    "name": "",
    "id": 1, // UUID
    "chldren": [{
            "id": 11, // UUID
            "type": "table", // TABLE TYPE
            "name": "Some Table 1",
            "meta": {},
            "dataSource": "..........."
        },
        {
            "type": "folder", // FOLDER TYPE
            "name": "",
            "id": 111, // UUID
            "chldren": [{
                "type": "folder",
                "name": "",
                "id": 1111, // UUID
                "chldren": [{
                    "id": 11111, // UUID
                    "type": "table",
                    "name": "Some Another Table",
                    "meta": {},
                    "dataSource": "..........."
                }]
            }]
        }
    ]
}]
1 Answers

I'd recommend using the Joi data validation library. It has had browser support since version 16.

An example is as follows e.g.

import Joi from '@hapi/joi';

const schema = Joi.object({
    type: Joi.string()
        .alphanum()
        .required(),

    id: Joi.number()
        .integer()

    // I've not defined the whole schema for your object...
})     

You can then validate your object using:

schema.validate({ type: 'folder', id: 1 });
// -> { error: null, value: { type: 'folder', id: 1 }}

Or:

try {
    const value = await schema.validateAsync({ type: 'folder', id: 1 });
}
catch (err) { }

You can get the TypeScript typings for Joi from here.

An example of this working can be found here.

Related