Coder Social home page Coder Social logo

stimiodev / json-schema-validator Goto Github PK

View Code? Open in Web Editor NEW

This project forked from pboettch/json-schema-validator

0.0 6.0 1.0 167 KB

Modern C++ JSON schema validator based on Niels Lohmann's JSON for Modern C++

License: Other

CMake 12.35% C++ 87.36% Shell 0.30%

json-schema-validator's Introduction

Build Status

JSON schema validator for JSON for Modern C++

What is it?

This is a C++ library for validating JSON documents based on a JSON Schema which itself should validate with draft-7 of JSON Schema Validation.

First a disclaimer: It is work in progress and contributions or hints or discussions are welcome. Even though a 2.0.0 release is imminent.

Niels Lohmann et al develop a great JSON parser for C++ called JSON for Modern C++. This validator is based on this library, hence the name.

External documentation is missing as well. However the API of the validator is rather simple.

New in version 2

Although significant changes have been done for the 2nd version (a complete rewrite) the API is compatible with the 1.0.0 release. Except for the namespace which is now `nlohmann::json_schema.

Version 2 supports JSON schema draft 7, whereas 1 was supporting draft 4 only. Please update your schemas.

The primary change in 2 is the way a schema is used. While in version 1 the schema was kept as a JSON-document and used again and again during validation, in version 2 the schema is parsed into compiled C++ objects which are then used during validation. There are surely still optimizations to be done, but validation speed has improved by factor 100 or more.

Design goals

The main goal of this validator is to produce human-comprehensible error messages if a JSON-document/instance does not comply to its schema.

By default this is done with exceptions thrown at the users with a helpful message telling what's wrong with the document while validating.

With 2.0.0 the user can pass a json_scheam::basic_error_handler-derived object along with the instance to validate to receive a callback each time a validation error occurs and decide what to do (throwing, counting, collecting).

Another goal was to use Niels Lohmann's JSON-library. This is why the validator lives in his namespace.

Weaknesses

Numerical validation uses nlohmann integer, unsigned and floating point types, depending on if the schema type is "integer" or "number". Bignum (i.e. arbitrary precision and range) is not supported at this time.

Currently JSON-URI with "plain name fragments" are not supported: referring to an URI with $ref: "file.json#plain" will not work.

How to use

The current state of the build-system needs at least version 3.6.0 of NLohmann's JSON library. It is looking for the json.hpp within a nlohmann/-path.

When build the library you need to provide the path to the directory where the include-file is located as nlohmann/json.hpp.

Build

Within a build-dir

git clone https://github.com/pboettch/json-schema-validator.git
cd json-schema-validator
mkdir build
cd build
cmake .. \
    -DNLOHMANN_JSON_DIR=<path/to/>nlohmann/json.hpp \
    -DJSON_SCHEMA_TEST_SUITE_PATH=<path/to/JSON-Schema-test-suite> # optional
make # install
ctest # run unit, non-regression and test-suite tests

As a subdirectory from within

# create an interface-target called json-hpp
add_library(json-hpp INTERFACE)
target_include_directories(json-hpp
    INTERFACE
        path/to/nlohmann/json.hpp)

# set this path to schema-test-suite to get tests compiled - optional
set(JSON_SCHEMA_TEST_SUITE_PATH "path/to/json-schema-test-suite")
enable_testing() # if you want to inherit tests

add_subdirectory(path-to-this-project json-schema-validator)

Building a shared library

By default a static library is built. Shared libraries are generated by using the BUILD_SHARED_LIBS-cmake variable:

In your initial call to cmake simply add:

cmake -DBUILD_SHARED_LIBS=ON

Code

See also app/json-schema-validate.cpp.

#include <iostream>

#include "json-schema.hpp"

using nlohmann::json;
using nlohmann::json_schema::json_validator;

// The schema is defined based upon a string literal
static json person_schema = R"(
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "A person",
    "properties": {
        "name": {
            "description": "Name",
            "type": "string"
        },
        "age": {
            "description": "Age of the person",
            "type": "number",
            "minimum": 2,
            "maximum": 200
        }
    },
    "required": [
                 "name",
                 "age"
                 ],
    "type": "object"
}

)"_json;

// The people are defined with brace initialization
static json bad_person = {{"age", 42}};
static json good_person = {{"name", "Albert"}, {"age", 42}};

int main()
{
	/* json-parse the schema */

	json_validator validator; // create validator

	try {
		validator.set_root_schema(person_schema); // insert root-schema
	} catch (const std::exception &e) {
		std::cerr << "Validation of schema failed, here is why: " << e.what() << "\n";
		return EXIT_FAILURE;
	}

	/* json-parse the people - API of 1.0.0, default throwing error handler */

	for (auto &person : {bad_person, good_person}) {
		std::cout << "About to validate this person:\n"
		          << std::setw(2) << person << std::endl;
		try {
			validator.validate(person); // validate the document - uses the default throwing error-handler
			std::cout << "Validation succeeded\n";
		} catch (const std::exception &e) {
			std::cerr << "Validation failed, here is why: " << e.what() << "\n";
		}
	}

	/* json-parse the people - with custom error handler */
	class custom_error_handler : public nlohmann::json_schema::basic_error_handler
	{
		void error(const std::string &path, const json &instance, const std::string &message) override
		{
			nlohmann::json_schema::basic_error_handler::error(path, instance, message);
			std::cerr << "ERROR: '" << path << "' - '" << instance << "': " << message << "\n";
		}
	};


	for (auto &person : {bad_person, good_person}) {
		std::cout << "About to validate this person:\n"
		          << std::setw(2) << person << std::endl;

		custom_error_handler err;
		validator.validate(person, err); // validate the document

		if (err)
			std::cerr << "Validation failed\n";
		else
			std::cout << "Validation succeeded\n";
	}

	return EXIT_SUCCESS;
}

Compliance

There is an application which can be used for testing the validator with the JSON-Schema-Test-Suite. In order to simplify the testing, the test-suite is included in the repository.

If you have cloned this repository providing a path the repository-root via the cmake-variable JSON_SCHEMA_TEST_SUITE_PATH will enable the test-target(s).

All required tests are OK.

Additional features

Default values

The goal is to create an empty document, based on schema-defined default-values, recursively populated.

json-schema-validator's People

Contributors

adri1mart1 avatar garethsb avatar ibell avatar justcametohelp avatar mabondarenko avatar pboettch avatar ronen avatar rpgillespie6 avatar vpasacek avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

adri1mart1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.