Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I validate a date using ajv json schema, without converting the date to string?

Tags:

node.js

ajv

I have an object which contains one or more properties of type date. I would like to validate the object using the ajv json schema validator package. I could convert the properties of type date to a string by using the toISOString(). But the object can be quiet big and thus I dont want to convert all the date-properties of the whole object. Is there a solution other than converting the date to a string? Could I somehow create a custom ajv schema validator?

 // My example schema
const schema = {
  "properties": {
    "createdAt": { 
       "type": "string",
       "format": "date-time"
    },
       "lastName": { "type": "string" },
       "firstName": { "type": "string" }
  }
};

// My example testobject
const testObj = {
   createdAt: new Date(),
   lastName: "Doe",
   firstName: "John"
}

// The validation
const validate = ajv.compile(schema);
const valid = validate(testObj);
if(!valid) console.log('Invalid: ' + ajv.errorsText(validate.errors));

This will do a console log, because the testObj.createdAt is a date and not a string.

like image 372
A. Bolleter Avatar asked Apr 04 '19 16:04

A. Bolleter


People also ask

How does JSON Schema validate JSON data?

The simplest way to check if JSON is valid is to load the JSON into a JObject or JArray and then use the IsValid(JToken, JsonSchema) method with the JSON Schema. To get validation error messages, use the IsValid(JToken, JsonSchema, IList<String> ) or Validate(JToken, JsonSchema, ValidationEventHandler) overloads.

Is date valid type in JSON?

For example, because JSON doesn't have a “DateTime” type, dates need to be encoded as strings. format allows the schema author to indicate that the string value should be interpreted as a date. By default, format is just an annotation and does not effect validation.

How does JSON Schema Define date format?

This is the recommended form of date/ timestamp. date : This SHOULD be a date in the format of YYYY-MM-DD. It is recommended that you use the "date-time" format instead of "date" unless you need to transfer only the date part. time : This SHOULD be a time in the format of hh:mm:ss.

How does JSON Schema validation work?

JSON Schema is a JSON-based format for defining the structure of JSON data. It provides a contract for what JSON data is required for a given application and how to interact with it. It can be used for validation, documentation, hyperlink navigation, and interaction control of JSON data.


1 Answers

Simply change your ajv schema from "type": "string" to "type": "object" and the built-in ajv date-time format will work. Here's a working fiddle.

You can also define a custom ajv format to validate a Date object (or string) like this:

ajv = new Ajv();

ajv.addFormat('custom-date-time', function(dateTimeString) {
  if (typeof dateTimeString === 'object') {
    dateTimeString = dateTimeString.toISOString();
  }

  return !isNaN(Date.parse(dateTimeString));  // any test that returns true/false 
});

... and invoke your custom format in the ajv schema like this:

const schema = {
  "properties": {
    "createdAt": {
      "type": "object",
      "format": "custom-date-time"

Putting it all together here's the code and a working fiddle for creating a custom date format:

// My example schema

const schema = {
  "properties": {
    "createdAt": {
      "type": "object",
      "format": "custom-date-time"
    },
    "lastName": {
      "type": "string"
    },
    "firstName": {
      "type": "string"
    },
    "required": [ 'createdAt', 'lastName', 'firstName' ],
    "additionalProperties": false,
  }
};

// My example testobject
const testObj = {
  createdAt: new Date(),
  lastName: "Doe",
  firstName: "John"
}


// The validation
ajv = new Ajv();

ajv.addFormat('custom-date-time', function(dateTimeString) {
  if (typeof dateTimeString === 'object') {
    dateTimeString = dateTimeString.toISOString();
  }

  return !isNaN(Date.parse(dateTimeString));  // return true/false 
});

const validate = ajv.compile(schema);
const valid = validate(testObj);

if (valid)
  alert('valid');
else
  alert('Invalid: ' + ajv.errorsText(validate.errors));
like image 155
Ananda Masri Avatar answered Oct 05 '22 06:10

Ananda Masri