Hi,
Today I need to write some software to make and consume JSON RPC calls.
I get this type of output returned from the JSON URL:
{"PPSN":"1234567T","FirstName":"Joe","Surname":"Bloggs","BirthSurname":"BLoggs","MothersBirthSurname":"Doe","Gender":"Male","Nationality":"UK","CivilStatus":"Married","DateOfMarriage":"20080531","SafeRegistrationLevel2":true,"DateOfDeath":"","DeceasedIndictor":false,"IsPPSNPurged":false}'
So when I found all those new JSON objects I thought – that’s handy I do not need to write all the code to marshal datatypes.
But I found two problems which caused me to pause.
jsonstring = 'http://mockdspapi.cloudapp.net/api/client/1234567T/19800101';
//httpresponse is a stringobject mapped to an entryfield.
httpresponse = JsonHandler.JsonRpcRequest(request = jsonstring);
Which returns:
{"error":{"data":"Invalid value. (offset: 0)","message":"Parse error","code":-32700},"jsonrpc":"2.0"}
Is this not what the method JsonRPCRequest() is for?
Using the WinHTTP external library this works i.e. I get my JSON string above returned:
http.Open('GET','http://mockdspapi.cloudapp.net/api/client/1234567T/19800101',FALSE);
http.Send();
httpresponse = http.ResponseText;
I wrote:
declare
jsonmanager = jsonhandler;
jsonstring = StringObject;
JV = JSONValue;
enddclare
begin
.
.
.
JV = jsonmanager.Parse(json = httpresponse);
jsonmanager.JsonObject2Object(jsonobj = JV , existing_obj = citizen );
//jsonerror is a field on the form
jsonerror = jsonmanager.ErrorText;
Field(citizen).UpdField();
End;
So citizen points to a matrixfield which is mapped to a userclass called 'dspdataset'.
Each of the attributes have the same name as the tag in JSON string
e.g. Citizen.PPSN
But I get the following error:
Class 'dspdataset' does not have or allow setting of attribute 'DeceasedIndictor'.
That’s got a value of ‘false’ – so I deleted that from the JSON string, then it complained about the other Boolean so I deleted that, then it complained about one of the varchars.
It was at that point I thought – I’m not doing something right here.
Anyone want to give me a nudge in the right direction?
Thanks
Adrian
Not sure why this message did not make the lists…
From: Adrian Williamson [mailto:adrian.w...@rationalcommerce.com]
Sent: 18 January 2018 13:59
To: 'openroa...@googlegroups.com' <openroa...@googlegroups.com>
Subject: Those JSON classes that just got added in the last patch....
Hi,
Today I need to write some software to make and consume JSON RPC calls.
I get this type of output returned from the JSON URL:
{"PPSN":"1234567T","FirstName":"Joe","Surname":"Bloggs","BirthSurname":"BLoggs","MothersBirthSurname":"Doe","Gender":"Male","Nationality":"UK","CivilStatus":"Married","DateOfMarriage":"20080531","SafeRegistrationLevel2":true,"DateOfDeath":"","DeceasedIndictor":false,"IsPPSNPurged":false}'
So when I found all those new JSON objects I thought – that’s handy I do not need to write all the code to marshal datatypes.
But I found two problems which caused me to pause.
jsonstring = 'http://mockdspapi.cloudapp.net/api/client/1234567T/19800101';
//httpresponse is a stringobject mapped to an entryfield.
httpresponse = JsonHandler.JsonRpcRequest(request = jsonstring);
Which returns:
{"error":{"data":"Invalid value. (offset: 0)","message":"Parse error","code":-32700},"jsonrpc":"2.0"}
Is this not what the method JsonRPCRequest() is for?
Using the WinHTTP external library this works i.e. I get my JSON string above returned:
http.Open('GET','http://mockdspapi.cloudapp.net/api/client/1234567T/19800101',FALSE);
http.Send();
httpresponse = http.ResponseText;
Ah there you are…
From: openroa...@googlegroups.com [mailto:openroa...@googlegroups.com] On Behalf Of Adrian Williamson
Sent: 18 January 2018 13:59
To: openroa...@googlegroups.com
--
You received this message because you are subscribed to the Google Groups "OpenROAD Users Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openroad-user...@googlegroups.com.
To post to this group, send email to openroa...@googlegroups.com.
Visit this group at https://groups.google.com/group/openroad-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/openroad-users/001b01d39064%246e1bee90%244a53cbb0%24%40rationalcommerce.com.
For more options, visit https://groups.google.com/d/optout.
Hi Adrian,
1.
The request you provided to the JsonRpcRequest() method is a URL rather than the JSON-RPC 2.0 request string (see http://www.jsonrpc.org/specification).
The parser detects that the request (your “jsonstring” variable) is not in JSON format (which should be contained in a StringObject).
Anyway, the method is provided to call 4GL procedures in an OpenROAD Server application via a JSON-RPC 2.0 interface (i.e. via the new OpenROADJSONRPC servlet).
The methods offers a lot of new features and removes the existing limitations for such calls, e.g.:
We have started to provide some demos on https://github.com/ActianCorp/OpenROAD_json
We will also provide more detailed usage information using a blog post.
2.
The boolean values (true/false) are definitely able to be parsed (they are getting represented as JsonNumber) and assigned to an OpenROAD object’s numeric attribute, as long as they are public.
Could it be that the attributes are private?
The JsonObject2Object() method can only assign values to public attributes.
BTW: You do not have to declare a JsonHandler variable, you can immediately use the JsonHandler attribute of the SessionObject class (CurSession.JsonHandler).
HTH.
Kind regards,
Bodo.
Bodo Bergmann
Principal Software Engineer
Actian | Engineering
Phone: +49.6103.3033.734
GESELLSCHAFTSANGABEN: Actian Germany GmbH | Geschäftsführer: Stephen Mark Padgett, Suzanne Gisborn, Gregory S. Hampton
Sitz der Gesellschaft: Hamburg| Handelsregister: Amtsgericht Hamburg | HRB 135991| USt-IdNr: DE252449897
From: openroa...@googlegroups.com
[mailto:openroa...@googlegroups.com] On Behalf Of Adrian Williamson
Sent: Thursday, January 18, 2018 2:59 PM
To: openroa...@googlegroups.com
Subject: [openroad-users] Those JSON classes that just got added in the last patch....
Hi,
--
Hi Bodo,
What would you call the mechanism that I’ve sited in question (1) – is it JSON over REST?
Is it possible to use the JsonRpcRequest method to call any other platform offering JSON-RPC?
Or is it only supported to call the OR App server?
I’m not worried about that at the moment but I thought I’d ask. (When App Server first turned up and I commissioned a SOAP wrapper for it I recall asking Ingres at the time – so how do we make SOAP calls out to other platforms)
So, #2 – all the attributes of the class are public – I’ve attached my ‘working notes’ on this.
TestDSP Frame – is where I’ve been kicking the tires.
DSPDataSet – is the class that the matrix field is mapped to.
It should run for you – the URL is in the public domain.
Cheers
Adrian
To view this discussion on the web visit https://groups.google.com/d/msgid/openroad-users/CY4PR06MB31907E20ADC3E3FBCCC1F4CB93EF0%40CY4PR06MB3190.namprd06.prod.outlook.com.
Hi Adrian,
1.
It seams that you just GET some JSON from a URL, you do not provide anything (method with parameters).
The JsonRpcRequest() method of the RemoteServer class should be able to send JSON-RPC 2.0 requests to other (non-OpenROAD) service providers.
We are also currently working on developing additional system class(es) to allow communication with URLs (similar to the “curl” utility).
2.
Just a quick look at the userclass DSPDataSet showed me that the datatypes and actual data do not match:
DeceasedIndicator is varchar(60) – Do you really want to assign a Boolean (numeric) value to it?
DateOfMarriage is a date - "20080531" is not a valid date format (at least not on my machine) – you should use ISO88601 format: "2008-05-31"
Formatting according your II_DATE_FORMAT should also work, so if your date format allows to enter 20080531 into a date field then you should be fine.
As you probably cannot change the service that provides the data, you will have to change your class:
DeceasedIndicator : smallint
DateOfMarriage: varchar(8)
Running the frame gave a different result (which of course could not be converted):
{"Code":"BAAS2","Message":"Not a Valid PPS 1234567F format, e.g. 9999999xx is a valid PPS"}
Therefore I used the JSON string you had written in your original email – and detected a problem in our implementation:
The JsonObject2Object() method only works if the member names are lowercase (The method succeeded after I changed the JSON string accordingly).
I am going to fix this.
Bodo.
To view this discussion on the web visit https://groups.google.com/d/msgid/openroad-users/007101d3910c%24811f8d00%24835ea700%24%40rationalcommerce.com.
Hi,
“That’s got a value of ‘false’ – so I deleted that from the JSON string, then it complained about the other Boolean so I deleted that, then it complained about one of the varchars.”
I had not got to the stage where I was worried about the data types – I had been deleting the Booleans until it reached a plain varchar – when it failed at that I started writing the original note for the forum.
The varchar failure is the ‘case issue’ you have identified.
As for the date – this works:
method ConvertDate(txt = varchar(2000) not null) =
declare
noquotes = varchar(2000) not null;
enddeclare
begin
noquotes = CurObject.StripQuotes(txt = txt);
return left(noquotes,4)+'-'+ left(right(noquotes,4),2) + '-'+ right(noquotes,2);
end;
As in the native text-to-date conversion works.
I’ve had to write my own JSONParser for now – getting a patch rolled out for this customer in the timescales needed for the release I’m working on would be challenging.
Cheers
Adrian
PS Being able to call SOAP might be nice too – or is SOAP too last century now?
To view this discussion on the web visit https://groups.google.com/d/msgid/openroad-users/CY4PR06MB3190AE8556F2903CBAB1F91293EF0%40CY4PR06MB3190.namprd06.prod.outlook.com.
I’m hoping that this post would clarify more how JSON / JSON-RPC works…
https://www.actian.com/company/blog/simplifying-development-openroad-json-rpc/
This should come along with Bodo’s example link on github: https://github.com/ActianCorp/OpenROAD_json
To view this discussion on the web visit https://groups.google.com/d/msgid/openroad-users/008801d3911d%24849d3250%248dd796f0%24%40rationalcommerce.com.
Hi Cristian,
I had looked at the those web pages, but in this case I wanted to decode JSON given to me by an HTTP Get on a URL (as Bodo pointed out).
I’ve had to write my own JSON to OpenROAD conversion classes as I will not be able to get this latest patch onto the target site in Q1.
Once we get the go-ahead to put any patch in place, I’ll switch over to the system classes.
Cheers
Adrian
To view this discussion on the web visit https://groups.google.com/d/msgid/openroad-users/CY4PR0601MB368376373EBB1F3FEE506C46F4EC0%40CY4PR0601MB3683.namprd06.prod.outlook.com.
As a follow-up on this discussion, I want to mention, that with
OpenROAD 11.2 there is no need to use any external library
(like WinHTTP) to get/put data from/to URLs.
You can use the new UrlConnection class to send HTTP GET/PUT requests and directly get the data retrieved into a
StringObject or a file
(if the data is JSON you can then parse it using the JsonHandler class).
See
https://docs.actian.com/openroad/11.2/index.html#page/LangRef%2FUrlConnection_Class.htm%23 .
There is also a video/course about using the UrlConnection class in the Actian Academy: https://academy.actian.com/openroad-using-the-urlconnection-class
Best regards,
Bodo.
To view this discussion on the web visit https://groups.google.com/d/msgid/openroad-users/002601d3955f%24da77c370%248f674a50%24%40rationalcommerce.com.
The link has been updated
https://academy.actian.com/openroad-urlconnection-class-connecting-openroad-to-the-outside-world
Best approach is to navigate to https://academy.actian.com
Then filter for OpenROAD content.
Paul