HarmonyCore icon indicating copy to clipboard operation
HarmonyCore copied to clipboard

Is there a way to create a dynamic return structure for arraylist items?

Open tscaff opened this issue 1 year ago • 6 comments

We have come across a method implementation that we were trying to do, and need a way to determine the easiest way to return dynamic JSON data elements that are controlled by a user configurable column layout that is NOT based on repository define structures.

Since all of our returned JSON ArrayList method data is based on repository structures and it returns the nice JSON data elements for each structure element, we weren't sure if there was a way to create a dynamic ArrayList type that could have any number of elements and data types so as to support a dynamic creation of a returned list of data elements in JSON.

For Example:

commonInformation is based off of a repository structure called COMMON_INFORMATION.

This responseData arraylist would be returned based off of a user configurable column set, not off of a repository structure.

{ "commonInformation": { "idNumber": 1, "NetworkId": "me", "ReturnCode": 0, "ReturnMessage": "", },

"responseData": [ { "FirstName": "Bill", "LastName": "Smith", "AccountNumber": 123456, }, { "FirstName": "Bill", "LastName": "Smith", "AccountNumber": 123456, } ] }

Without a concrete definition in Harmony Core that matches it, is there any way to convert that data and create the dynamic structure, like our example in responseData?

tscaff avatar Oct 25 '23 22:10 tscaff

Can you just return an ArrayList of String; you can put anything you want into each string in the ArrayList? Of course the tooling won't make the JSON for you, you'd have to do that manually with Json.Utf8JsonWriter

SteveIves avatar Oct 25 '23 22:10 SteveIves

So would the responseData portion look like this?

{ "commonInformation": { "idNumber": 1, "NetworkId": "me", "ReturnCode": 0, "ReturnMessage": "", },

"responseData": "{ "responseData": [ { "FirstName": "Bill", "LastName": "Smith", "AccountNumber": 123456, }, { "FirstName": "Bill", "LastName": "Smith", "AccountNumber": 123456, } ]}" }

Is this what you are suggesting?

tscaff avatar Oct 25 '23 23:10 tscaff

For out or inout Array of string parameters would be something like: [ "string 1", "string 2", "string 3" ]

Each string might contain a JSON object if that's what you return. Obviously this is just the part of the response for one parameter, in Bridge it would be the value of a named property for the parameter.

SteveIves avatar Oct 26 '23 19:10 SteveIves

Hello.

So when reviewing the results from a test we did using a modified version of our code to use the JsonWriter object in DBL, we were able to return the following string to the requester via HC.

{ "responseData": "{"responseData":[{"AccountNumber":"0","FirstName":"MASEKED","LastName":"MASKED","CurrentBalance":"14489.9800000000","InterestRate":"000000","PhoneNumber":"0","DateOpened":"0","Status":""},{"AccountNumber":"0","FirstName":""MASKED","LastName":""MASKED","CurrentBalance":"222.8700000000","InterestRate":"000000","PhoneNumber":"0","DateOpened":"0","Status":""},{"AccountNumber":"1002818","FirstName":""MASKED","LastName":""MASKED","CurrentBalance":"6248.6200000000","InterestRate":"000000","PhoneNumber":"0","DateOpened":"0","Status":""}]}" }

One issue the requester had was the backslashes(which were removed when I posted this to the GitHub site) in the returned string was causing them some concern on parsing the data back into a JSON object.

For Example when viewed in raw form, the quotes around the AccountNumber property are escaped using a prefixing backslash(\).

I believe the backlashing is the mechanism by which the data is escaped in JSON to prevent problems with the response being properly formatted and returned.

There is not a means of removing those backslashes and maintaining the integrity of the returned response data is there?

tscaff avatar Nov 01 '23 17:11 tscaff

I have been faced with this requirement before, there may be better options now and I was using signalR but if you return an arraylist of Json it would get munged by the serialization, I think effectively serialized into Json twice.

Jeff helped us make a custom endpoint which deserialized the list again to get back to Json. This was an older version of HC so there may be better options available now.

It was something like this:

public partial class aspHub extends Hub<IaspHubClient>

    public async method jsonlist, @Task
        aRequest, @asp.jsonlist_Request
    proc
        data resultstr,    string
        data callContext = ^as(Context.Items["RPCContext"], @aspService)
        data result = await callContext.jsonlist(aRequest)
        data jsonlist_actualresult = new jsonlist_Response() { jsonlist = new List<Object>() }
       
        foreach resultstr in result.jsonlist
        begin
            jsonlist_actualresult.jsonlist.add(JsonConvert.DeserializeObject(resultstr))
        end
        jsonlist_actualresult.errorcode=result.errorcode
        await Clients.Caller.jsonlist_Result(jsonlist_actualresult)
    endmethod

danellis06460 avatar Nov 01 '23 17:11 danellis06460

Thanks, that is a really good suggestion, but I will probably have to have some in depth assistance on that adjustment, as we are trying to move towards a 100% generated HC service implementation and I would have to be sure I don't clobber my interface definition exposure and create manual work, if there is no other way to implement this besides a customer endpoint. Would I have to create a separate interface all together to prevent interference during auto-generation using 'harmonycore regen'?

tscaff avatar Nov 01 '23 17:11 tscaff