JSON external data transfer

This forum allows developers to post programming tips and coding techniques that may be useful to other Visual LANSA developers. The information contained in this forum has not been validated by LANSA and, as such, LANSA cannot guarantee the accuracy of the information.
User avatar
Jiri
Posts: 40
Joined: Thu Feb 11, 2016 11:41 pm

JSON external data transfer

Post by Jiri » Tue Jun 14, 2016 11:31 pm

We have requirements to exchange some data between LANSA web application and 3rd party. The communication can be single way:
LANSA issue request GET (...) and should receive back some data in JSON format.
JSON is nativelly used by WAMs or VL-WEB in V14, therefore it should be possible to process them directly (without need to use Integrator). What is the simplest method how to do it?
Does anybody have an example?

jyoung
Posts: 297
Joined: Thu Jan 21, 2016 6:43 am
Location: Oklahoma City, OK USA

Re: JSON external data transfer

Post by jyoung » Wed Jun 15, 2016 1:35 am

Hi Jiri,

We just hooked up with a 3rd party http api posting and receiving data, not JSON though.

If you are "getting" the data from the client browser take a look at the #PRIM_WEB.HttpRequest. You can see an example of it in the xDemoWebWeatherItem in the samples.

http://docs.lansa.com/14/EN/LANSA016/PR ... EQUEST.htm

We could not use that however, because the API we were calling does not support CORS, so the request had to come from the server. Unfortunately #PRIM_WEB is not available in server modules so we ended up having to use Integrator.

Hope this helps,
Joe

User avatar
Jiri
Posts: 40
Joined: Thu Feb 11, 2016 11:41 pm

Re: JSON external data transfer

Post by Jiri » Fri Jun 24, 2016 9:45 pm

Any other idea? JSON is format proferred by LANSA and used in WAMs, VL-WEB... why it is problem to process JSON from other source, if it will pass LANSA naming rules??

marco.kam
Posts: 7
Joined: Thu Apr 07, 2016 2:03 am

Re: JSON external data transfer

Post by marco.kam » Sat Jun 25, 2016 10:27 am

Hi Jiri,

The weather widget example that @jyoung mentioned is probably the best place to see some sample code.

There are a few primitives that you can use to both generate JSON (to post to a 3rd party service) as well as read and extract information from JSON into RDMLX.

From the documentation here:
http://docs.lansa.com/14/EN/LANSA016/

Please refer to the following
PRIM_WEB.HttpRequest
PRIM_WEB.HttpResponse
PRIM_WEB.Json
PRIM_WEB.JsonArray
PRIM_WEB.JsonBoolean
PRIM_WEB.JsonElement
PRIM_WEB.JsonNumber
PRIM_WEB.JsonObject
PRIM_WEB.JsonString

Here is some relavant code:

Code: Select all

* -----------------------------------------------------
* Creating JSON (can be used to post to other services)
* -----------------------------------------------------
* Create a Json object as the root element
#Json.CreateRootObject Result(#Root)
 
* Set the values for the name and title properties on the root object
#Root.InsertString Key('name') String('Marco')
#Root.InsertString Key('title') String('Principal Consultant')
 
* Create an array for the property 'skills'
#Root.InsertArray Key('skills') Result(#Skills)
 
* Insert a new skill object into the skills array
#Skills.InsertObject Result(#Skill)
* Set the values for the name and years properties on the skill object
#Skill.InsertString Key('name') String('LANSA')
#Skill.InsertNumber Key('years') Number(12)
 
* Insert a new skill object into the skills array
#Skills.InsertObject Result(#Skill)
* Set the values for the name and years properties on the skill object
#Skill.InsertString Key('name') String('javascript')
#Skill.InsertNumber Key('years') Number(5)


* -----------------------------------------------------
* Making a request and processing JSON
* -----------------------------------------------------
#Request.URL := <url to 3rd party service>

Evtroutine Handling(#Request.Completed)
If (#Request.Response *IsNot *null)
Case (#Request.Response.StatusCode)
When (= 200)
* Get the JSON from the response
       #Json := #Request.Response.Content

* Loop through the array in the response
       For Each(#Employee) In(#Json.RootItem)
              * Get the value of the id on each object in the array
#Id := #Employee<"id">.AsString
Endfor
Otherwise
* HTTP error
Endcase
EndifEndroutine
The first set of code will generate a JSON object that looks like this:
{
"name": "Marco Kam",
"title": "Principal Consultant",
"skills": [{
"name": "LANSA",
"years": 12
}, {
"name": "javascript",
"years": 5
}]
}

The second set of code will make a request to a 3rd party API, then parse the JSON that comes back. In this case it is assuming that an array of employees is coming back.

Note that #PRIM_WEB is only available in Web Page Objects. The code is generating javascript on the client side, and as a result it can only communicate with 3rd party APIs if the service supports CORS (https://developer.mozilla.org/en-US/doc ... ntrol_CORS).

There is no CORS restriction on the server, but as @jyoung mentioned, you'll have to use Integrator if you are making HTTP requests on the server side.

MikeS
Posts: 7
Joined: Wed Jun 01, 2016 12:22 am

Re: JSON external data transfer

Post by MikeS » Thu Oct 13, 2016 7:52 pm

Hi Marco

I can see from your example how you reference the root elements of the JSON document, but can you clarify how I go about referencing the 'nested' array elements of the Skills array within the Employee element.

Thanks

Mike

User avatar
Stewart Marshall
Posts: 366
Joined: Thu Nov 05, 2015 5:25 pm

Re: JSON external data transfer

Post by Stewart Marshall » Fri Oct 14, 2016 11:32 am

Hi Mike

All VL Json objects can act as a collection. This means you can try to iterate over an element whether it's an array or not. All you need is the FOR command.

In this case, you can directly access the "Skills" object created for the employee, which is the root item. Once you have a reference to the element, you can get the individual values from the elements

Code: Select all

For Each(#Skill) In(#Json.RootItem.Item<"Skills">)
    #Name := #Skill.Item<"Name">.AsString
    #Years := #Skill.Item<"Years">.AsString
...
EndFor
Here's a complete example

Code: Select all

Begin_Com Role(*EXTENDS #PRIM_WEB) Height(712) Width(1024)

Define_Com Class(#Prim_web.Json) Name(#Json)
Define_Com Class(#Prim_web.JsonObject) Name(#Root) Reference(*Dynamic)
Define_Com Class(#Prim_web.JsonArray) Name(#Skills) Reference(*Dynamic)

Define_Com Class(#PRIM_LIST) Name(#List1) DisplayPosition(1) Left(8) Parent(#COM_OWNER) TabPosition(1) Top(8) Height(394) Width(439) ColumnLines(False) RowLines(False)
Define_Com Class(#PRIM_LIST.String) Name(#ColumnLabel1) DisplayPosition(1) Parent(#List1) ColumnWidth(382) ColumnUnits(Proportion) ColumnCaption('Click here to get skills') ColumnCaptionType(Caption)

Evtroutine Handling(#COm_owner.CreateInstance)

* Create a Json object as the root element
#Root <= #Json.CreateRootObject

* Set the values for the name and title properties on the root object
#Root.InsertString( 'Name' 'Marco' )
#Root.InsertString( 'Title' 'Principal Consultant' )

* Create an array for the property 'skills'
#Skills <= #Root.InsertArray( 'Skills' )

#Com_owner.AddSkill( LANSA 12 )
#Com_owner.AddSkill( "JavaScript" 5 )
#Com_owner.AddSkill( "HTML" 10 )

Endroutine

Mthroutine Name(AddSkill)
Define_Map For(*Input) Class(#Prim_alph) Name(#Name)
Define_Map For(*Input) Class(#Prim_nmbr) Name(#Year)
Define_Map For(*Result) Class(#Prim_web.JsonObject) Name(#Skill) Pass(*By_Reference)

* Insert a new skill object into the skills array
#Skill <= #Skills.InsertObject

#Skill.InsertString( 'Name' #Name )
#Skill.InsertNumber( 'Years' #Year )

Endroutine

Evtroutine Handling(#ColumnLabel1.ColumnClick)

* Loop through the "skills" object array in the response
For Each(#Skill) In(#Json.RootItem.Item<"Skills">)

Add_Entry To_List(#List1)

#ColumnLabel1.CurrentItem.Value := #Skill.Item<"Name">.AsString + " " + #Skill.Item<"Years">.AsString

Endfor

Endroutine

End_Com
Stewart Marshall

LANSA Product Centre

MikeS
Posts: 7
Joined: Wed Jun 01, 2016 12:22 am

Re: JSON external data transfer

Post by MikeS » Fri Oct 14, 2016 11:53 pm

Hi Stewart

Thanks great. Thanks for your speedy response.

Mike

User avatar
Jiri
Posts: 40
Joined: Thu Feb 11, 2016 11:41 pm

Re: JSON external data transfer

Post by Jiri » Thu Mar 02, 2017 11:53 pm

Hello,
Cou please give as an example of HTTP request with basic authentication? The published is only to unauthorised server.
For authorisation, it is necessary add some information to HTTP header (may vary by requirements), for exaple some user and password.

User avatar
Stewart Marshall
Posts: 366
Joined: Thu Nov 05, 2015 5:25 pm

Re: JSON external data transfer

Post by Stewart Marshall » Fri Mar 03, 2017 10:19 am

Hi Jiri

You can access the headers of an HTTP request using the Headers property.

Code: Select all

Define_Com Class(#Prim_web.HttpRequest) Name(#Request)
#Request.Headers.Add( "Key" "Value" )
Sorry, but I don't have any specific examples.

Regards
Stewart Marshall

LANSA Product Centre

User avatar
Jiri
Posts: 40
Joined: Thu Feb 11, 2016 11:41 pm

Re: JSON external data transfer

Post by Jiri » Fri Jun 09, 2017 10:08 pm

Anyone have an example, how to pass basic authentication (User & Password) to LANSA HTTP request header?
On web, there is lot of examples for PHP, Nette etc. but we are not able to implement it il LANSA.
If the authorisation data (User and Password) are not passed by browser, browser will ask for it. We need to omit this step - means pass the info in HTTP header.
The mentioned method:
#Request.Headers.Add( "Key" "Value" )
works, but we did not success with passing the values.

Post Reply