%WriteJSONFromObject retrieves too much of database when complex relationships are involved

Hi all,

We're creating a series of RESTful APIs that output data from a Cache database (made up of global storage that we've mapped to classes). I'm running into some problems with object-to-JSON conversions when relationships are involved. Eg:

ParentClass has children relationship to ChildClass

ChildClass has parent relationship to ParentClass

If you %WriteJSONFromObject on an instance of ChildClass, it will retrieve the instance of ChildClass you're asking for, and it will retrieve the ParentClass as a JSON sub object, via the parent relationship (this part is OK), AND it will retrieve EVERY other instance of ChildClass as sub-sub objects, via the children relationship of ParentClass (not OK).

I totally understand why it is doing this, as it's simply retrieving every related object, but for our database this ends up retrieving almost every instance of a given object, and more, when you're only asking for one!

What to do? Here's my thoughts:

  • Can you setup relationships that are only one-way? Eg, a child that knows about a parent, but a parent that doesn't know about the child(ren)? I think even if you can, we can't do this here as we're using these relationships to work out subscripts in the mapped globals.
  • I've had a brief look at the new JSON stuff in Cache 2016, but that seems to be using an abstract %Object class, but we're dealing with mapped persistent classes here. Does it help us?
  • Is there a way of limiting the 'depth' that %WriteJSONFromObject goes into the object?

I have created a related work-around where the client sends an class path, an id, and an empty JSON object of the properties they want to retrieve, and my service converts this to a %ZEN.ProxyObject, loops through it, and populates it with those same properties from the instance, then converts back to a JSON to send back to the client. We could maybe use this, but it would mean sending hard-coded JSON 'templates' for every object :(

Thanks!

Chris

  • 0
  • 0
  • 369
  • 0
  • 1

Answers

I had a client that had this exact problem.   The JSON interfaces that exist today intentionally try to take a concise approach rather than try to provide options to handle every possible situation.   Bottom-line is that this means for this situation you will need to create your own method of handling this.  The good is that this is not necessarily too difficult to create a flexible methodology to do this.  

What my client did was to create a code generation method that would introspect on the class definition at compile time and produce a method that would build a Proxy object (old way, 2016 and higher would use Dynamic Object structures) of exactly what they wanted to have in the JSON.  Then the method to produce the JSON from an object would use the Proxy or Dynamic object.   For this client they created a parameter on the class that provided direction regarding how to handle collection properties.  

It may also be possible to create a general utility class that defines  new property parameters to manage this and the code generation method.   Then have the your classes inherit from this to add in the desired functionality.