#1 2015-09-11 15:15:49

cypriotcalm
Member
Registered: 2015-02-18
Posts: 122

JSON result format

Hello!

What is the reason for the JSON result as an object with the array "result" {result:[...]}?

Why can't be returned something like {obj1} for one object and [{obj1},{obj2}] for a list of objects? Is there an important reason for that?

 TFullname = record
   Firstname: String;
   Lastname: String;
 end;

 TFullnames = array of TFullname;

 IFullnameService = interface(IInvokable)
   function GetFullnameArray: TFullnames;
 end;

// result JSON
{  
   result:[  
      [  
         {  
            Firstname:"My",
            Lastname:"SQL"
         },
         {  
            Firstname:"Maria",
            Lastname:"DB"
         }
      ]
   ]
}

// wish
      [  
         {  
            Firstname:"My",
            Lastname:"SQL"
         },
         {  
            Firstname:"Maria",
            Lastname:"DB"
         }
      ]

Thank you for your answer!

Offline

#2 2015-09-11 15:48:45

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 13,048
Website

Re: JSON result format

The reason to nest the returned values in a "result" array by default, is that it allows to return the corresponding session ID, in sicClientDriven mode.
Even if you are not in sicClientDriven mode, it shares the same layout.
BTW, this is close to the JSON-RPC format.

You can return plain JSON, using the  TServiceFactoryServer.ResultAsJSONObject or TServiceFactoryServer.ResultAsJSONObjectWithoutResult properties.
See http://synopse.info/files/html/Synopse% … #TITLE_423

Offline

#3 2015-09-11 16:23:54

cypriotcalm
Member
Registered: 2015-02-18
Posts: 122

Re: JSON result format

:-) Ah ok, thank you very much for the explanation!

Offline

#4 2021-01-15 08:56:31

squirrel
Member
Registered: 2015-08-13
Posts: 116

Re: JSON result format

Hi ab

I used the TFullname records posted by cypriotcalm and added them to the calculator in the sample project 27 (Project14ServerHttpWrapper), since this declaration is already done in there to test the result:

aServer.ServiceDefine(TServiceCalculator,[ICalculator],sicShared).ResultAsJSONObjectWithoutResult := true;

I added a test function like this:

function TServiceCalculator.GetSingleFullname: TFullname;
begin
  Result.Firstname := 'First Name';
  Result.Lastname := 'Last Name';
end;

and expected the result to not contain "Result":

However, it looks like it always encapsulates it in a Result ie

  {"Result":{"Firstname":"First Name","Lastname":"Last Name"}}

Is that the expected behaviour of this property, or did I misunderstood the reason for it?  Is the idea behind this property not to send the data without result, ie:

{"Firstname":"First Name","Lastname":"Last Name"}

?

Is it possible to send a record like that without Result being added?  It seems that using RawJson also always include Result?

Offline

#5 2021-01-15 09:08:05

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 13,048
Website

Re: JSON result format

Yes, it is the expected behavior, since the "Result" here is the name of the function result itself.

You need to write:

procedure TServiceCalculator.GetSingleFullname(out FirstName, LastName: RawUtf8);

Offline

#6 2021-01-15 09:17:30

squirrel
Member
Registered: 2015-08-13
Posts: 116

Re: JSON result format

Thanks ab

It can get very complicated to add/update out parameters on many functions when a standard long/nested record result is to be returned, especially if the expected output is prepopulated as a record by a universal function. 

Is there maybe an event on TSQLRestServerFullMemory that can be overridden before the data is sent to manually remove the leading {"Result": and trailing " from the outgoing json string, or another property that can be set to not add it at all?

Offline

#7 2021-01-15 09:41:39

Vitaly
Member
From: Russia
Registered: 2017-01-31
Posts: 167
Website

Re: JSON result format

You can create your own TSQLRestRoutingREST-based class and assign it to your <TSQLRestServerFullMemory-instance>.ServicesRouting property. Not an easy way, but there you'll be able to adjust almost everything.

Offline

#8 2021-01-15 10:11:32

squirrel
Member
Registered: 2015-08-13
Posts: 116

Re: JSON result format

Thanks Vitaly that looks like an option, but also looks scary, since I'm not too sure what impact that will have.

I suppose that would entail overriding both TSQLRestServerURIContext.ServiceResultStart and TSQLRestServerURIContext.ServiceResultEnd and replacing them with versions that look for a new boolean property which causes them to not make any changes to wr at all?

Last edited by squirrel (2021-01-15 10:12:38)

Offline

#9 2021-01-15 10:53:33

Vitaly
Member
From: Russia
Registered: 2017-01-31
Posts: 167
Website

Re: JSON result format

Sorry, I'm not sure about ServiceResultStart/End since I haven't used them. I took a quick look at these methods, I am afraid it might be not enough. Hope, Arnaud or other guys will advise you something better.

We're using custom ServicesRouting and TServiceCustomAnswer in services for a heavy project (FHIR-specified), where we had to override almost everything to make it automatic and compatible with third-party software: fhir+json/fhir+xml output/input data formats, different http-methods, custom meaningful headers, and much other stuff...

Last edited by Vitaly (2021-01-15 11:03:57)

Offline

#10 2021-01-15 11:13:00

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 13,048
Website

Re: JSON result format

Using TServiceCustomAnswer with a custom formatting method may be indeed the easiest.

Offline

Board footer

Powered by FluxBB