Everyone who has read my previous posts knows that I enjoy the JSON format, mainly for its easy readability, adapt very good to classes, very interoperable with most web tools, and usually faster than other human readable formats, such as YAML).
A couple of days ago I was fooling around with the new Interfaces in LV2020 (see other cool features in Tom McQuillan’s Yotube Channel) and I may have figured out how to solve an issue that dated since I first started with OOP in LabVIEW.
JSON and OOP
One of my first big projects that I worked, I needed to provide a WebService interface for a web page consuming the application information in JSON format. At the time, I thought I could solve all my problems with default LV Function, which provides conversion to string, but that doesn’t happen.
LabVIEW support for JSON is very weak at least, almost non-existent, aside these two native functions. So, I figured out later (too late) that this function does not support some data types, including very important ones as the LabVIEW Object, Enum, Path and Timestamp. For that time I used converted clusters to do the job, although I never liked the result.
This input does not support other data types, such as enums, refnums, file paths, and fixed-point numbers.
Lack of Ideas?
In the search for why LabVIEW doesn’t evolve in this area for sometime, I found something in LabVIEW Idea Exchange. In fact, two topics related to this post idea.
- Allow enums in “flatten to json”/”unflatten from json”
- Flatten to JSON – Allow any data type on the “anything” input
The results of them both were pretty straight forward. Apparently the developers of the “Flatten to JSON” primitive didn’t correlate these types to JSON specification, but no word mentioned why objects (lvclass) are not supported.
In my opinion, it is just some stubborn programmer that didn’t want to ship a wrapper code to convert these LV Datatypes to some universal type compatible with JSON. Sorry for my harsh words.
To the sake of the users, we have a community that developed functions to this job, so alternatively to LabVIEW native functions we have some toolkits that fulfill this gap like JKI JSON, JSONtext and others.
However, for objects I found only this option JSON Object Serialization that works, but is a paid option. Maybe for a customer project in my company I would try to purchase but for my personal projects I would try to avoid.
Interfaces, one solution
Why Interfaces? In LV2020, Interfaces may have solved this problem definitely by leaving this responsibility for converting the private data to the class.
The trick is to create an interface and leave this job to the class, what may be the correct decision, because in theory only the class must be responsible for its data.
Below an example of the Interface that I implemented.
Then I change the inheritance of my class to inherit from this interface.
Then after overriding these two methods I can use the Interface method everywhere I want to convert my objects to JSON, and the class itself will decide what properties to export or to import. It is not a magical block that does it for you, but it is pretty interesting, isn’t it?
I also realized that I could’ve done that in an old way, with malleable VIs, calling the same-named method VI. But when using array things can get more complicated, but it would work. In a way, it is the same idea, but with Interfaces you have a contract and it is way clearer.
But wait, were malleable VI for classes a trial for Interfaces?
Let me know what you think in the comments.
If you are interested, below is the link for the project in Gitlab.
Actually I really like easiness in programming. Although I think the concept of Interfaces is great, this approach is not very scalable considering heavy composition projects with lots of classes.
Parallel to this idea I am also running a test code to create a LV Object Converter to JSON, with some available libraries after a research in the web. I already did the PoC, and was based on some libraries such as the LVClass API from F. Normandin, the JKI JSON Toolkit, Flatten to XML Primitive, Data Type Parsing Palette, Flattened LVOOP LAVAG, some RegEx, and of course, the RFC8259 JSON Specification.
EDIT: Included a post from LAVAG where it is described the structure of the string flattened LV Object. That may help me with the conversion.
2 thoughts on “Interfaces, OOP and JSON”
Nice article (again)!
I think I’m not quite understanding this bit though:
> this approach is not very scalable considering heavy composition projects with a lots of classes
Could you expand at all?
Actually, in this approach, you would use the primitive Flatten to JSON function, so, this means every class would inherit from this interface. In big composition systems, class inside class inside class, etc.., every time you would call this interface you would need to concatenate this class recursively until you hit the main caller (top level class).
Again, like I said, with small systems, it is ok, with big systems maybe, it really depends on your effort to convert your current working classes to match this idea.