JSON

Introduction

The web application code for libzeep contained an implementation of expression language, a simple language used in the HTML templates. The variables in this language look and act a bit like objects in JavaScript. And then REST support was added and more support for JSON was needed.

For C++ there is already a very good JSON library available from Niels Lohmann. I tried to use this initially, but it didn’t fit well into the rest of libzeep. Still I liked the way it worked and so I tried to create something that is source code compatible, however fancy stuff like JSON Pointer and JSON Patch are not available (yet).

This library just provides code to parse and write JSON. It stores the data in an efficient way, allows easy manipulation and also can use the same mechanism of serialization as the XML library.

The JSON element

The main data structure in this library is zeep::json::element, this is the representation of a JSON object and thus can contain various types of data. See this synopsis on how to use it.

    using namespace zeep::json::literals; 
    using json = zeep::json::element;

    json j1;

    /* Fill a JSON object with some data, the type is detected automatically */
    j1["b"] = true;
    j1["i"] = 1;
    j1["f"] = 2.7183;
    j1["s"] = "Hello, world!";
    j1["ai"] = { 1, 2, 3 };
    j1["n"] = nullptr;
    j1["o"] = { { "b", false }, { "i", 2 } };
    j1["o"]["s"] = "sub field";

    std::cout << j1 << '\n';

    /* Construct a JSON object by parsing a raw string */

    json j2 = R"(
    {
        "b": true,
        "i": 1,
        "f": 2.7183,
        "s": "Hello, world!",
        "ai": [ 1, 2, 3 ],
        "n": null,
        "o": {
            "b": false,
            "i": 2,
            "s": "sub field"
        }
    }
    )"_json;

    std::cout << j2 << '\n';

    assert(j1 == j2);

There is also support for enums, see the following example. The idea is, you call the init method of the value_serializer for the enum once to initialize the global mapping of enum values to strings. The name parameter is optional, but required if you use this serializer also in a SOAP controller.

	enum class MyEnum { aap, noot, mies };
	zeep::value_serializer<MyEnum>::init("MyEnum",
	{
		{ MyEnum::aap, "aap" },
		{ MyEnum::noot, "noot" },
		{ MyEnum::mies, "mies" }
	});

	json j{ MyEnum::aap };
	assert(j.as<std::string>() == "aap");

STL-like interface

The zeep::json::element class acts as an STL container, see the class reference for more information. But to give you an idea:

    json j;

    /* Make j an array */
    j = zeep::json::element::array({ 1, 2, 3 });
    j.push_back(4);
    j.emplace_back("five");

    assert(j == R"([ 1, 2, 3, 4, "five" ])"_json);

    /* Now make j an object, this will erase the data and initialize a new object */
    j = zeep::json::element::object({ { "a", true }, { "b", "2" } });
    j.emplace("c", 3);

    assert(j == R"({ "a": true, "b": "2", "c": 3 })"_json);