Search code examples
jsonschemarapidjson

Rapidjson giving validation success even when required field is missing


I was expecting rapidjson to give a validation error as my json file doesn't include one of the 'required' field mentioned in the schema. However, due to some reasons this doesn't happen.

dbconf.json(json file)

{
        "MAX_CONNECTION_PER_HOST":20,
        "QUEUE_IO_SIZE":10485,
        "Garbage":50000
}

Here's the test code along with the schema.

#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
#include "rapidjson/schema.h"
#include <rapidjson/stringbuffer.h>
#include<iostream>
#include<string>
#include<fstream>

using namespace std;

const char g_plJsonSchema[]="{\
                             \"$schema\": \"http://json-schema.org/draft-04/schema#\",\
                             \"title\": \"Schema\",\
                             \"description\": \"JSON schema for validating Json file\",\
                             \"type\": \"object\",\
                             \"properties\": {\
                             \"MAX_CONNECTION_PER_HOST\": { \"type\": \"number\" },\
                              \"QUEUE_IO_SIZE\": { \"type\": \"number\" },\
                              \"REQUEST_LOW_WATER_MARK\": { \"type\": \"number\" },\
\"required\": [\
\"MAX_CONNECTION_PER_HOST\",\
\"QUEUE_IO_SIZE\",\
\"REQUEST_LOW_WATER_MARK\"\
]\
      }\
}";

int main()

{
        rapidjson::Document l_peerAddSchemaDoc, l_peerAddDataDoc;
        l_peerAddSchemaDoc.Parse(g_plJsonSchema);
        if(l_peerAddSchemaDoc.HasParseError())
        {
                printf("JSON schema file is not a valid JSON file\n");
                return -1;
        }
        std::ifstream l_confDataIStream("dbconf.json");
        std::string l_confDataIStreamStr((std::istreambuf_iterator<char>(l_confDataIStream)),(std::istreambuf_iterator<char>()));
        l_peerAddDataDoc.Parse(l_confDataIStreamStr.c_str());


        rapidjson::SchemaDocument l_schemaDocument(l_peerAddSchemaDoc);
        rapidjson::SchemaValidator l_SchemaValidator(l_schemaDocument);

        if(!l_peerAddDataDoc.Accept(l_SchemaValidator))
        {
                rapidjson::StringBuffer sb;
                l_SchemaValidator.GetInvalidSchemaPointer().StringifyUriFragment(sb);
                printf("Invalid schema: %s\n", sb.GetString());
                printf("Invalid keyword: %s\n", l_SchemaValidator.GetInvalidSchemaKeyword());
                sb.Clear();
                l_SchemaValidator.GetInvalidDocumentPointer().StringifyUriFragment(sb);
                printf("Invalid document: %s\n", sb.GetString());
        }
else
printf("\nJson file validated with the given schema successfully\n");

        return 0;
}

I get the following output

Json file validated with the given schema successfully

Solution

  • Your issue here is required should be at the root level, and not inside properties. In fact, you currently have an invalid schema, as all values of keys inside properties should be objects only.

    {
      "$schema": "json-schema.org/draft-04/schema#",
      "title": "Schema",
      "description": "JSON schema for validating Json file",
      "type": "object",
      "properties": {
        "MAX_CONNECTION_PER_HOST": {
          "type": "number"
        },
        "QUEUE_IO_SIZE": {
          "type": "number"
        },
        "REQUEST_LOW_WATER_MARK": {
          "type": "number"
        }
      },
      "required": [
          "MAX_CONNECTION_PER_HOST",
          "QUEUE_IO_SIZE",
          "REQUEST_LOW_WATER_MARK"
        ]
    }
    

    I validated the schema against the instance using https://www.jsonschemavalidator.net for testing.