JSON: Difference between revisions

From Bitpost wiki
(Created page with "JSON is as simple as possible but no less. Genius. === C++ === We will use boost::json wherever possible. Keep updating it, and move to c++ std json if it becomes a thing....")
 
No edit summary
 
(7 intermediate revisions by the same user not shown)
Line 2: Line 2:


=== C++ ===
=== C++ ===
We will use boost::json wherever possible.  Keep updating it, and move to c++ std json if it becomes a thing.
We will use boost::json wherever possible.  Keep updating it, and move to c++ std json if it becomes a thing.  We still use nlohmann for quicktype and postgres-jsonb.


```
==== Warnings ====
* YOU CAN'T USE `using namespace boost::json` without fucking up std::string!  Arrogant boost author decided his string was better - fine - but name it something else you ass.
* You can't extract easily from a const object with brackets (it [https://www.boost.org/doc/libs/1_77_0/libs/json/doc/html/json/ref/boost__json__object/operator_lb__rb_.html has no const version] because it returns a reference).  What bullshit.
# Nope, not gonna work, you can't use [] on a const object, durrr...
string order = jMsg["client_order_id"].as_string().c_str();
# Workaround one liner
string order = jMsg.at("client_order_id").as_string().c_str();
 
==== Header ====
     when we need nlohmann:
     when we need nlohmann:
 
         using namespace nlohmann::json;
         using nlohmann::json;
 
     when we need boost:
     when we need boost:
 
         // boost/json.hpp
         // boost/json.hpp
         using boost::json::value;
         using boost::json::object; // << most common!
         using boost::json::array;
         using boost::json::array;
         using boost::json::object;
         using boost::json::value; // << avoid, too generic
         using boost::json::value_from;
         using boost::json::value_from;
         using boost::json::parse;
         using boost::json::parse;
         using boost::json::serialize;
         using boost::json::serialize;
         using boost::json::kind;
         using boost::json::kind;
```
        // OR: Use auto to short-circuit the bullshit whenever possible.
        auto jBars = jResponse["bars"].as_array();
 
==== Examples ====
===== constructors =====
            object j;
            j["my-name"] = "Heisenburg";
            j["my-number"] = 42;
            // initialization list
            object jv =
            {
                { "pi", 3.141 },
                { "happy", true },
                { "name", "Boost" },
                { "nothing", nullptr },
                { "answer",
                    {
                        { "everything", 42 }
                    }
                },
                {"list", {1, 0, 2}},
                {
                    "object",
                    {
                        { "currency", "USD" },
                        { "value", 42.99 }
                    }
                }
            };
       
            // string literal
            string strThing = R"(
{
  "name": "blah",
  "number": 123
}
            )";
            object jThing = parse( strThing );
 
===== Parsing =====
            object jBody = parse(payload).as_object();
            if ( !jBody.if_contains( "sub" ) || !jBody.if_contains( "role" )) return;     
            sub_  = jBody["sub"].as_string();
            role_ = jBody["role"].as_int64();
            // NOTE you can't do an assignment for some reason...?
            FAIL: string sub = jBody["sub"].as_string();
            // But you can provide a constructor param.  Just weird.
            string sub( jBody["sub"].as_string() );
            // OUTPUT
            ss << j;
            string strMyJ = serialize( j );


==== Library history ====
==== Library history ====
* rapidjson: I started with this.  It is brutally low-level and cumbersome (fast?  not to develop against...).
* rapidjson: I started with this.  It is brutally low-level and cumbersome (fast?  not to develop against...).
* nlohmann: This was great to code with.  Very elegant and straightforward.  I moved towards boost to get better performance and a library with "more eyeballs".  But this is still used by quicktype, which is used by my Postgres template code, which is really nice... and even tho quicktype is kinda dead... I'm keeping it for as long as I can.
* nlohmann: This was great to code with.  Very elegant and straightforward.  I moved towards boost to get better performance and a library with "more eyeballs".  But this is still used by quicktype, which is used by my Postgres template code, which is really nice... and even tho quicktype is kinda dead... I'm keeping it for as long as I can.
* boost: I started using boost::json on boost v 1.77, when it seemed to be generally not insane (like its predecessor spirit was...).  It's slightly cumbersome, not that bad, and hopefully will get better.
* boost: I started using boost::json on boost v 1.77, when it seemed to be generally not insane (like its predecessor property_tree/spirit/bleh was...).  It's slightly cumbersome, not that bad, and hopefully will get better.

Latest revision as of 18:32, 6 September 2021

JSON is as simple as possible but no less. Genius.

C++

We will use boost::json wherever possible. Keep updating it, and move to c++ std json if it becomes a thing. We still use nlohmann for quicktype and postgres-jsonb.

Warnings

  • YOU CAN'T USE `using namespace boost::json` without fucking up std::string! Arrogant boost author decided his string was better - fine - but name it something else you ass.
  • You can't extract easily from a const object with brackets (it has no const version because it returns a reference). What bullshit.
# Nope, not gonna work, you can't use [] on a const object, durrr...
string order = jMsg["client_order_id"].as_string().c_str();
# Workaround one liner
string order = jMsg.at("client_order_id").as_string().c_str();

Header

   when we need nlohmann:

       using nlohmann::json;

   when we need boost:

       // boost/json.hpp
       using boost::json::object; // << most common!
       using boost::json::array;
       using boost::json::value; // << avoid, too generic
       using boost::json::value_from;
       using boost::json::parse;
       using boost::json::serialize;
       using boost::json::kind;

       // OR: Use auto to short-circuit the bullshit whenever possible.
       auto jBars = jResponse["bars"].as_array();

Examples

constructors
           object j;
           j["my-name"] = "Heisenburg";
           j["my-number"] = 42;

           // initialization list 
           object jv = 
           {
               { "pi", 3.141 },
               { "happy", true },
               { "name", "Boost" },
               { "nothing", nullptr },
               { "answer", 
                   {
                       { "everything", 42 }
                   }
               },
               {"list", {1, 0, 2}},
               {
                   "object", 
                   {
                       { "currency", "USD" },
                       { "value", 42.99 }
                   } 
               }
           };
       
           // string literal
           string strThing = R"(
{
  "name": "blah",
  "number": 123
}
           )";
           object jThing = parse( strThing );
Parsing
           object jBody = parse(payload).as_object();
           if ( !jBody.if_contains( "sub" ) || !jBody.if_contains( "role" )) return;      
           sub_  = jBody["sub"].as_string();
           role_ = jBody["role"].as_int64();

           // NOTE you can't do an assignment for some reason...?
           FAIL: string sub = jBody["sub"].as_string();
           // But you can provide a constructor param.  Just weird.
           string sub( jBody["sub"].as_string() );

           // OUTPUT
           ss << j;
           string strMyJ = serialize( j );

Library history

  • rapidjson: I started with this. It is brutally low-level and cumbersome (fast? not to develop against...).
  • nlohmann: This was great to code with. Very elegant and straightforward. I moved towards boost to get better performance and a library with "more eyeballs". But this is still used by quicktype, which is used by my Postgres template code, which is really nice... and even tho quicktype is kinda dead... I'm keeping it for as long as I can.
  • boost: I started using boost::json on boost v 1.77, when it seemed to be generally not insane (like its predecessor property_tree/spirit/bleh was...). It's slightly cumbersome, not that bad, and hopefully will get better.