Jump to content
David Schwartz

General JSON question

Recommended Posts

Posted (edited)

I'm calling a service and I get back a JSON response packet that's got a bunch of sections in it, and each one has a structure to it. Most contain an array of things; some of those items themselves contain arrays, and some contain a list of items.

 

I'm using TJSONObject to process this data.

 

What I'm doing is picking out two sections, say ARY1 and ARY2. One can have 10-20 elements and the other 3-5.

 

Then I go through them using a for...in statement, and for each of the elements, I have code that picks out a half-dozen field values that I'm interested in (among 10-20 in each type of element). Eg,

 

    ntry1.TryGetValue<integer>('request_info.credits_used', FCreditsUsed);
    ntry1.TryGetValue<integer>('request_info.credits_remaining', FCreditsRemaining);

 

From time to time, one or more of the field values is missing -- meaning the name isn't there. If it's there and it's blank, that's fine. But since they can be missing, I have to use TryGetValue<T>(...) everywhere which is rather cumbersome.

 

Each one of these elements gets loaded into a class instance which is put into a TList<T> collection. 

 

Another class contains the two TList<T> collections (representing the two arrays) and then I use that to process the data. I might have 10 to 50 or so of these in a matrix.

 

I could put the two arrays into different TDatasets, but I don't really see any benefit in that.

 

Is this approach what would typically be taken? Or would it be more typical to just access things in the JSONObject directly? 

eg.,

if doc.TryGetValue<string>('a.b['+n.ToString+'].'+aFldName, s) then fFldName = s else fFldName = '';

where 'n' indicates which array (1 or 2) and each aFldName is referred in each in each.

 

This approach seems very brittle. But it seems a bit simpler. So I'm sticking with my classes and lists. (But I have something not being freed properly that's being quite a PITA to track down, and I'm thinking it's related to the structures I'm using.)

 

I haven't seen any examples that show JSON processing where non-trivial data is being retrieved, so I'm just curious if there are better approaches.

 

Edited by David Schwartz

Share this post


Link to post

A lot of JSON libs filter out empty values and never writes those name-value pairs.

When i built 0.5, 1.0 and 2.0 of my own REST "API" i liked that "style" because it can take the payload size down quite.

In JS null and undefined are different values... kind of. So a null (part of JSON spec) would set the parsed object member to null while a missing name will set (or leave) any declared members "undefined". Since i know what to expect (more or less as it seems you do too) it is not a problem.

 

Your approach above (the second code line) thus looks quite ok to me.

 

I should also say that i mostly consume JSON in JS and not so much in Delphi (of course a lot of payloads are JSON, but when parsing a payload server-side i could just throw an exception as soon as any little thing is amiss).

 

Regarding the details on TJSONObject and RTTI and all i have no ide, i use a dynamic JSON lib (no RTTI) and simply loop/recurse as needed, it is a "just tree" after all. Mainly array or object splits processing in two and the rest is recursive.

 

HTH

Share this post


Link to post
6 hours ago, David Schwartz said:

Is this approach what would typically be taken?

Probably yes.

 

On the other hand, I have an expert which generates custom classes from a JSON string and the fields are properties of a custom type which is not only nullable but also "nothingable" for this reason. (silly name I know). It's not necessarily a better approach, I'm just allergic to string constatns in the code.

 

Share this post


Link to post
11 hours ago, Attila Kovacs said:

Probably yes.

 

On the other hand, I have an expert which generates custom classes from a JSON string and the fields are properties of a custom type which is not only nullable but also "nothingable" for this reason. (silly name I know). It's not necessarily a better approach, I'm just allergic to string constatns in the code.

 

Interesting ... is this 'expert' accessible somewhere?

Share this post


Link to post
1 hour ago, David Schwartz said:

is this 'expert' accessible somewhere?

No, as it depends on modified emba/another non-free codes I will not be able to publish it ever... 😕

  • Sad 1

Share this post


Link to post

In general, you can't losslessly map a wider set of values to a tight one (well, thanks Cap'n Obvious). Integer is MinInt..MaxInt and JSON value is MinInt..MaxInt + null + undefined/non-existing. So you either got to make assumptions based on subject (f.e.x, if you're reading naturals - -1 could indicate any missing/invalid value) or to check actual value before each assignment (if JSONDoc.GetValue(..)).

Edited by Fr0sT.Brutal
  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×