Please rotate your tablet to be horizontal.

You can dismiss this notice but please note that this experience has not been designed for mobile devices and so will be less than optimal

Back To Schedule

Help! My Codebase has 5 JSON Libraries

How Generic Programming Came to the Rescue

15:15 - 16:15 Monday 12th September 2022 MDT Summit 2 & 3 / Online D
Advanced
Templates & Metaprogramming

In 2019 working on a RESTful cloud oriented C++ application, everything was JSON. Inbound communication was handled with an ASIO based web server, RESTinio, and used RapidJSON to handle the API payload. Outbound was handled by CPPRESTSDK which had its own JSON implementation. To handle authorization, we picked the best C++ JSON Web Token (JWT) library but that was written on top of PicoJSON, a small minimalistic unmainted library. We then had 3 different JSON libraries to work with and mix together.

How do we make this work together? “Why don’t you template out the logic and metaprogram a traits implementation?” Geeze, Thanks Gareth! So that’s what I did.

Generic programming is writing algorithms in such a way that the type can be specified later. Using templates the algorithm can operate on different types if they satisfy certain traits (or implement a certain concept). JSON Web Tokens should follow the same algorithm regardless of the JSON implementation - this seemed like a useful case for applying generic programming.

Six months and a lot of learning later, I had opened a pull request against the JWT-CPP library.
Using templates, SFINAE, and static assertions I was able to abstract the “JSON” out of the JSON Web Token (JWT) logic. I am able to answer questions like: How can the compiler know…
What is the signature of a function? Does it match a known signature? Is it close enough?
If a type has a member function? What is the return type of the method? Can it differentiate between static and member functions?
Yes. The compiler is really that well informed and the tools and techniques exist to programmatically answer them at compile time.

Templating the JSON “value and types” played in favor with the existing design of a C++ single file header only library. Being an Open-source project it was important to maintain the existing compiler requirements, this bound the implementation to C++11 however there are C++17 features (i.e. `std::void_t`) and experimental features (i.e. `std::experimental::is_detected`) which are back-ported.

A JSON Traits needs to declare a generic value type, and concert basic types which match the JWT’s family of RFC defined claims (which are JSON keys) such as object, string, or double. All the types were substituted into templates to check for concepts, for instance, `object_type` needs to be iterable, so a `constexpr` value is set if begin and end methods are present. Some traits are optional and substitution failure is not an error.

With several of the most popular JSON libraries like Niel Lohamn’s and Boost’s supported, this approach can work for any project looking to decouple the application logic from a library specific container. There are some drawbacks, such as complexity and mind melting error messages. Recent compilers with support for Concepts makes future possibilities very exciting.

Christopher McArthur

JFrog

Christopher McArthur, Conan Developer Advocate
Chris has been giving back to the open source community with exploit database containers, C++/ CMake build system maintenance, and other OSS projects for nearly ten years. He began his career as a C++ developer and has since then added other languages including Golang and Typescript to his skill set. Prior to joining the Conan team at JFrog, Chris previously worked in the video broadcast and mobile advertising industries on a variety of projects. His diverse experiences include Blockchain, low-level hardware networking, distributed systems security, and cloud-native DevOps. As a developer advocate for JFrog, Chris deals with Conan, Chris shares his deep to the knowledge of DevOps and Package Management to the C++ Community globally.