JsonDocument
Description
JsonDocument
stores a JSON document in memory. It owns the memory referenced by JsonArray
, JsonObject
, and JsonVariant
.
JsonDocument
contains a fixed-size memory pool, with a monotonic allocator. This design allows ArduinoJson to be very efficient but requires some discipline on your side:
- Because the size is fixed, you need to specify the size when you create the
JsonDocument
- Because the allocator is monotonic, it cannot release memory when you call
JsonObject::remove()
for example.
I strongly recommend against using a global JsonDocument
because you would be troubled by the monotonic allocator, and would make inefficient use of your RAM.
On the contrary, I recommend declaring a short-lived JsonDocument
that you use only in your serialization functions.
For details on how to choose the right capacity for the JsonDocument
, please read How to determine the capacity of the JsonDocument
?
StaticJsonDocument
vs DynamicJsonDocument
You can choose to store your JsonDocument
in the stack or in the heap:
- Use a
StaticJsonDocument
to store in the stack (recommended for documents smaller than 1KB) - Use a
DynamicJsonDocument
to store in the heap (recommended for documents larger than 1KB)
You must specify the capacity of a StaticJsonDocument
in a template parameter, like that:
StaticJsonDocument<256> doc;
For a DynamicJsonDocument
, however, you must use a constructor argument:
DynamicJsonDocument doc(2048);
JsonDocument
vs JsonVariant
JsonDocument
shares many features with JsonVariant
; however, there is one big difference: JsonDocument
has value semantics, whereas JsonVariant
has reference semantics.
On the one hand, because JsonDocument
owns the data, if you copy a JsonDocument
, you get a complete clone.
// make a clone of the JsonDocument
DynamicJsonDocument doc2 = doc1;
On the other hand, because JsonVariant
is a reference, if you copy a JsonVariant
, you only clone the reference:
// make a new reference to the same variant
JsonVariant var2 = var1;
Using a JsonDocument
When you create a JsonDocument
, it is initially empty. At this stage, it’s neither an object, nor an array, and JsonDocument::isNull()
returns true
.
When you insert the first value in the JsonDocument
, it automatically changes its type to match the call. If you use the JsonDocument
like an array, it becomes an array; if you use the JsonDocument
as an object, it becomes an object.
Here is a JsonDocument
that implicitly becomes an object:
DynamicJsonDocument doc(1024);
doc["answer"] = 42;
// the doc contains {"answer":42}
Here is a JsonDocument
that implicitly becomes an array:
DynamicJsonDocument doc(1024);
doc.add(42);
// the doc contains [42]
Sometimes, however, you’ll need to explicitly convert the JsonDocument
without adding a value; for example, because you want to create an empty object. In this case you can call JsonDocument::to<T>()
:
DynamicJsonDocument doc(1024);
JsonObject obj = doc.to<JsonObject>();
// the doc contains {}
JsonDocument::to<T>()
clears the document and converts it to the specified type. Don’t confuse this function with JsonDocument::as<T>()
that returns a reference only if the requested type matches the one in the document.
Member functions
as<T>()
casts the root to the specified type (e.g.JsonArray
orJsonObject
)add()
adds elements to the root arraycapacity()
returns the capacity of the memory poolclear()
empties the document and resets the memory poolcontainsKey()
tests if the root object contains the specified keycreateNestedArray()
creates a nested array attached to the rootcreateNestedObject()
create a nested object attached to the rootgarbageCollect()
reclaims leaked memory blocksoperator[]
gets or sets values in the documentoverflowed()
tells if the memory pool was large enoughis<T>()
tests the type of the rootisNull()
tells if the document is null or emptymemoryUsage()
tells how many bytes are used in the memory poolnesting()
returns the number of nesting layers in the documentremove()
removes an element (or member) at the specified index (or key)set()
replaces the root with the specified valueshrinkToFit()
reduces the capacity of the memory pool to match the current usage*size()
returns the number of elements (or members) that the root array (or object) containsto<T>()
clears the document and converts it to the specified type (e.g.JsonArray
orJsonObject
)
Example
Here is a program that deserializes a JSON document and stores it in the stack:
StaticJsonDocument<200> doc; // <- a little more than 200 bytes in the stack
char json[] = "{\"hello\":\"world\"}";
deserializeJson(doc, json);
const char* world = doc["hello"];
Here is a program that serializes a JSON document stored in the heap:
DynamicJsonDocument doc(200); // <- 200 bytes in the heap
doc["hello"] = "world";
serializeJson(doc, Serial); // {"hello":"world"}