boostorg / json

A C++11 library for parsing and serializing JSON to and from a DOM container in memory.
https://boost.org/libs/json
Boost Software License 1.0
424 stars 94 forks source link

Insert pointer to object into parent object #1015

Closed MGraefe closed 3 weeks ago

MGraefe commented 3 weeks ago

In my project, we construct a lot of json::objects from scratch and then serialize it. It often happens, that a function creates a single 'inner' object, lets call it inner, which then has to be wrapped in multiple slightly different parent objects. These parent objects are then serialized.

So basically I am doing the following:

const object inner = createInner();
object parentA = createParent("foo");
object parentB = createParent("bar");
parentA["inner"] = inner; // copy happening :(
parentB["inner"] = inner; // copy happening :(
doSomething(serialize(parentA));
doSomething(serialize(parentB));

The problem here is that I have to create a copy of inner for each parent prior to the serialization. I can't move inner into parent because it's needed by multiple parents. What I would like to do instead, is to just "link" inner into the parent with a (shared) pointer or something similar, so I can still serialize the whole parent object in a single call, but I don't have to copy the inner object. Basically I want to do something like this:

parentA["inner"] = &inner;

This is more or less how it works in JavaScript where everything is done with references and to actually "deep-copy" an object you have to do JSON.parse(JSON.stringify(obj)).

Is there a way to solve this problem with boost::json? Obviously the method above doesn't work for good reasons, but I'm wondering if I can do some magic with the memory resource objects, a custom type or a custom serializer?

grisumbras commented 3 weeks ago

I'm afraid, I don't see how this can be done with Boost.JSON. As an alternative, I can suggest keeping your data in a custom type, and then directly serialize from that type into JSON. We don't yet support direct serialisation, but I'm working on it. I suspect, I won't finish the work before the deadline for 1.86 release, so this means you'll have to wait until 1.87.

If you do need to stick to json::objects, then I don't have even a potential solution for you.

MGraefe commented 3 weeks ago

Thanks for the insights! I will experiment a bit with custom types, maybe I can make it work. The thing is, we're looking for an alternative to nlohmann's library, mainly because of the high memory usage of JSON objects. Having to copy the objects is even worse. Currently I'm serializing the inner and parent objects separately and then merge the raw strings....that works but it's really fragile and cumbersome.

Anyway, thanks again and I think this can be closed as I don't have any concrete idea how to implement it.