p4-web

Working with JSON

JSON is a file format common on the web. The starter code includes json.hpp, a library for working with JSON in C++. To use the library, place the following at the top of a .cpp file:

#include "json.hpp"
using nlohmann::json;

JSON format

The JSON format is a simple text-based standard for representing structured data. It consists of the following data types:

Constructing a JSON object

The json.hpp library defines the json type to represent a JSON value. The documentation has an example of constructing a json object in C++ code. We summarize the example here. Suppose we wanted to construct the following JSON object:

{
  "pi": 3.141,
  "happy": true,
  "name": "Niels",
  "nothing": null,
  "an_array": [1, 0, 2],
  "an_object": {
    "currency": "USD",
    "value": 42.99
  }
}

This object has the following key-value pairs:

We can create the JSON object in C++ as follows:

json j2;
j2["pi"] = 3.141;
j2["happy"] = true;
j2["name"] = "Niels";
j2["nothing"] = json();
j2["an_array"] = {1, 0, 2};
j2["an_object"] = {
  {"currency", "USD"},
  {"value", 42.99}
};

The value for a particular key can be read using the same subscript syntax:

cout << j2["pi"] << endl;      // prints 3.141
cout << j2["answer"] << endl;  // prints {"everything":42}
j2["tau"] = 6.283;             // inserts "tau":6.283 into j2
cout << j2["tau"] << endl;     // prints 6.283

A JSON object can also be created with a C++ initializer list, as in:

j2["an_object"] = {
  {"currency", "USD"},
  {"value", 42.99}
};

Each element of the C++ initializer list must be another initializer list, containing both a key and a value. In this example, the key "currency" is associated with the string "USD", and the key "value" is associated with the number 42.99.

The following creates the same object as j2 above using initializer lists:

json j2 = {
  {"pi", 3.141},
  {"happy", true},
  {"name", "Niels"},
  {"nothing", nullptr},
  {"an_array", {1, 0, 2}},
  {"an_object", {
      {"currency", "USD"},
      {"value", 42.99}
    }
  }
};

JSON arrays

Build a JSON array using push_back().

json output;

json j4 = {
  {"happy", true},
  {"pi", 3.141}
};
output.push_back(j4);

json j5 = {
  {"happy", true},
  {"pi", 3.14159265359}
};
output.push_back(j5);

The resulting JSON is

[
    {
        "happy": true,
        "pi": 3.141
    },
    {
        "happy": true,
        "pi": 3.14159265359
    }
]

Reading JSON from a stream

JSON-formatted data can be read from a stream into a json object using operator>>:

json j3;
cin >> j3;

Writing JSON to a stream

A json object can be inserted directly into a stream. However, it does not get “pretty printed” with proper indentation. Instead, use the dump() member function to convert a json object into a string and then insert the string into a stream:

json j4 = {
  {"happy", true},
  {"pi", 3.141}
};
string str2 = j4.dump(4) + "\n";  // dump with indentation using 4 spaces
cout << str2;                    // print the dumped string

This results in the following:

{
    "happy": true,
    "pi": 3.141
}

The key-value pairs are ordered alphabetically by key.

Compute the content length for a request or response from the length of the dumped string.

size_t content_length = str2.length();

Pitfall: the string should include a trailing newline before computing the length.