2

I'd like to have tooling to perform certain validations on JSON. Explanation with examples:

Given JSON fragment:

{
    "optionsMinValue": 0
    "optionsMaxValue": 56
    "options": [
        {
            "name": "name1",
            "value": 0
        },
        {
            "name": "name2",
            "value": 1
        },
        {
            "name": "name3",
            "value": 56
        }
  ]
}

Validation examples:

  • Given the fragment above, the validation of optionsMaxValue should pass.

  • Given the fragment above, if optionsMaxValue is changed to 55, then the validation should fail.

Added bonus validation:

  • Check whether an item is included in the options array for every integer between optionsMinValue and optionsMaxValue. In other words, in the given fragment the array should contain 57 items with an item for each value from 0 to 56.

Existing tooling:

Does tooling exist that can be used relatively easily to perform these sorts of checks?

First thought is that something like json-schema validation could be done. It has been a few years since I looked at that as an option, so my hope is that tooling has emerged that is a homerun on this.

7
  • 1
    cuelang looks promising. Anyone have input on it before I go down the rabbit hole? cuelang.org Commented Mar 30, 2022 at 14:39
  • 2
    json-schema.org. They list implementations, among other things. Commented Apr 16, 2022 at 20:30
  • @Ouroborus is there something more specific that can enable this sort of check? I've done a lot of reading, and it has so many options that it seems that I'd have to get to expert level before knowing how to implement it. Commented Apr 19, 2022 at 15:53
  • Hi @GaTechThomas, Where are you going to validate your JSON data, i.e. Rest API or By pasting it into a window/console? If it's rest JOI is one the best tools i have worked with. Commented Apr 23, 2022 at 12:41
  • @Ouroborus are you interested in getting a bounty for this? The existing answers are not viable and the bounty clock is about to end. Commented Apr 23, 2022 at 13:15

3 Answers 3

4
+25

Ajv JSON schema validator - github link

const schema = {
  type: "object",
  properties: {
    name: {type: "string"},
    value: {type: "number", minimum: 0, maximum: 55},
  },
  required: ["name", "value"],
  additionalProperties: false,
}

const option = {
    "name": "name1",
    "value": 0
},

const validate = ajv.compile(schema)
const valid = validate(data)
if (!valid) console.log(validate.errors)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/4.4.0/ajv.min.js"></script>

Sign up to request clarification or add additional context in comments.

Comments

1

Joi package is best for these kind of validations

following Joi schema can be used to solve your requirement

Joi.object({
  optionsMinValue: Joi.number().min(0).max(30).required(),

  optionsMaxValue: Joi.number().min(56).max(100).required(),

  options: Joi.array().items(
    Joi.object({
      name: Joi.string().required(),
      value: Joi.number().min(0).max(56).required(),
    })
  ),
});

Following is a sample code that works for your scenario

const inputData = {
  optionsMinValue: 0,
  optionsMaxValue: 56,
  options: [
    {
      name: "name1",
      value: 0,
    },
    {
      name: "name2",
      value: 1,
    },
    {
      name: "name3",
      value: 56,
    },
  ],
};

const Joi = joi; // for node.js use - const Joi = require("joi");

// Schema for validation
const schema = Joi.object({
  optionsMinValue: Joi.number().min(0).max(30).required(),

  optionsMaxValue: Joi.number().min(56).max(100).required(),

  options: Joi.array().items(
    Joi.object({
      name: Joi.string().required(),
      value: Joi.number().min(0).max(56).required(),
    })
  ),
});

const runValidation = (schema, inputData) => {
  const validationResult = Joi.compile(schema)
    .prefs({ errors: { label: "key" }, abortEarly: false })
    .validate(inputData);

  if (validationResult.error) {
    // Validation failed
    console.log("Error, validation failed");
    // Set error message to string
    const errorMessage = validationResult.error.details
      .map((details) => details.message)
      .join(", ");
    console.log("failure reason - ", errorMessage);
    return;
  }
  console.log("validation passed");
};
runValidation(schema, inputData);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/joi-browser.min.js"></script>

Comments

0

Even if you use an existing tool, you should write validation rules for that tool. Since you are not an expert in any of these tools, it may be easier to write a few lines of code in your preferred language. For example, in JavaScript it might look like this:

function validateJson(jsonToValidate, maxValue = 56) {
  if (jsonToValidate.optionsMaxValue !== maxValue) {
    console.log("Failure on optionsMaxValue.");
    return false;
  }
  if (jsonToValidate.options.length !== maxValue+1) {
    console.log("Incorrect number of items.");
    return false;
  }
  let values = jsonToValidate.options.map(a => a.value).sort();
  if (values[0] !== 0 || values[maxValue] !== maxValue) {
    console.log("Values out of desired sequence.");
    return false;
  }
  let sum = values.reduce((a, b) => a + b, 0);
  if (sum !== maxValue * (maxValue + 1) / 2) {
    console.log("Values out of desired sequence.");
    return false;
  }
  console.log("Validation PASSED.");
  return true;
}

Let's try with truncated json object:

let jsonSample = {
  "optionsMinValue": 0,
  "optionsMaxValue": 2,
  "options": [{
      "name": "name1",
      "value": 0
    },
    {
      "name": "name2",
      "value": 1
    },
    {
      "name": "name3",
      "value": 2
    }
  ]
};

function validateJson(jsonToValidate, maxValue = 56) {
  if (jsonToValidate.optionsMaxValue !== maxValue) {
    console.log("Failure on optionsMaxValue.");
    return false;
  }
  if (jsonToValidate.options.length !== maxValue+1) {
    console.log("Incorrect number of items.");
    return false;
  }
  let values = jsonToValidate.options.map(a => a.value).sort();
  if (values[0] !== 0 || values[maxValue] !== maxValue) {
    console.log("Values out of desired sequence.");
    return false;
  }
  let sum = values.reduce((a, b) => a + b, 0);
  if (sum !== maxValue * (maxValue + 1) / 2) {
    console.log("Values out of desired sequence.");
    return false;
  }
  console.log("Validation PASSED.");
  return true;
}

validateJson(jsonSample, 2);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.