You are doing JSON APIs wrong.
When you use JSON to call an API – not a REST API, but something like JSON-RPC – you will usually want to encode
one of several possible messages.
Your request body looks like this:
{
"type": "MessageWithA",
"data": {
"a": 5
}
}
Or like this:
{
"type": "MessageWithB",
"b": 5
}
However, that’s bad. Here’s how you should do it:
{
"messageWithA": {
"a": 5
}
}
Or
{
"type": "MessageWithA",
"data": {
"messageWithA": {
"a": 5
}
}
}
Why? Stream parsers.
Stream parsers?
There are two ways of processing a JSON telegram. The first is to read the telegram into a JSON object,
and then process the object inside-out.
This usually takes the form of
if (event["type"] == "MessageWithA") {
handleAMessage(event["data"]);
}
However, this has the unavoidable overhead of allocating an object for every part of the JSON tree.
Especially if you are decoding into a well-typed internal data structure, you allocate this object just to throw it
away shortly after. This creates unnecessary memory overhead.
A faster way is with a stream parser. A stream parser lexes the input text into a stream of JSON tokens,
such as BeginObject, KeyString, BeginArray, String, String, Int, EndArray, EndObject
for { "a": ["b", "c", 5]}
.
These tokens are then consumed by a recursive parser, usually generated, that produces the internal data structure
directly. In other words, there never exists a recursive data structure for t