VL 15 WEB API Put / Patch / Create

This Q&A forum allows users to post and respond to "How Do I Do ....." questions. Please do not use to report (suspected) errors - you must use your regional help desk for this. The information contained in this forum has not been validated by LANSA and, as such, LANSA cannot guarantee the accuracy of the information.
Post Reply
Joerg Hamacher
Posts: 124
Joined: Thu Feb 11, 2016 12:01 am

VL 15 WEB API Put / Patch / Create

Post by Joerg Hamacher »

Hi everybody,

in LANSA documentation, LANSA Tutorial and LEARN LANSA I can only find explanations and samples for for requesting data (GET) from external APIs.
I did not find anything that explained to me how to call the create and update operations of the VL Web API and how to transfer the values into JSON.
A customer wants us to send product data from our ERP system that is running on IBMi to an external PIM system that is offering a JSON REST API to receive the data.
Availiable HTTP verbs are POST for new entries and PATCH for updates.

Does anyone have a simple VL Web API example for preparing data (JSON) and sending data to an external API in order to create or update entries in a table?
Or does anyone know of such samples in LANSA documentation, maybe I've missed something?

Many thanks in advance,
Joerg
User avatar
Dino
Posts: 477
Joined: Fri Jul 19, 2019 7:49 am
Location: Robbinsville, NC
Contact:

Re: VL 15 WEB API Put / Patch / Create

Post by Dino »

Hi

Check the example Web Page
xDemoWebServicesLiveDemoDownload (XDEMO_126)

which retrieves a contact, search for some, allow you to update information in it using the PUT method, etc.

Just notice that all is good in windows, if you want to publish this kind of restful services in the IBM, you need to follow the steps outlined here:
viewtopic.php?f=3&t=2356
restfulput.jpg
restfulput.jpg (329.88 KiB) Viewed 12453 times
Joerg Hamacher
Posts: 124
Joined: Thu Feb 11, 2016 12:01 am

Re: VL 15 WEB API Put / Patch / Create

Post by Joerg Hamacher »

Hi Dino,

I'm sorry but I do not have XDEMO_126 in my repository.
I have VL 15 Build 4403 Last EPCs 150040 / 150046.

I did a partition initialization using "Sample material" option but this did not bring me XDEMO_126.
Are there special import files on IBMi or on my development PC that contain this object and that I have to import?

Best regards,
Joerg
User avatar
Dino
Posts: 477
Joined: Fri Jul 19, 2019 7:49 am
Location: Robbinsville, NC
Contact:

Re: VL 15 WEB API Put / Patch / Create

Post by Dino »

This is an old example (around 2018) that was provided to show how to use restful apis with LANSA, maybe came with the examples at one poitn. I am attaching here the server module required as well, notice that the server module is kind of like the initial version of the publishing the server module as a restful api option we have today, so that one its structured a bit different.

notice the disclaimer in it:

Code: Select all

* Disclaimer:
* These examples are provided in an "AS IS" basis to demonstrate the use of the LANSA REST API.
* Use of this examples in an end user application with or without modification is the responsibility of the user.
* No warranty or indemnification of any kind is implied.
Attachments
QuickExport20210820091208_XDEMOW_94.zip
(13.61 KiB) Downloaded 1237 times
QuickExport20210820091046_XDEMO_126.zip
(16.74 KiB) Downloaded 1227 times
User avatar
Dino
Posts: 477
Joined: Fri Jul 19, 2019 7:49 am
Location: Robbinsville, NC
Contact:

Re: VL 15 WEB API Put / Patch / Create

Post by Dino »

Lets say you have a table called PSLmini with the fields EMPNO, SURNAME, GIVENAME and SALARY, and you created a restful server module using the File/ New /Server Module /Web Api / option in the Visual LANSA menu, and called your server module TEST92SM , so the service Name is TEST92SM and you used TEST92ON for the Object Noun name, so you have a server module like this:
restful01.jpg
restful01.jpg (86.31 KiB) Viewed 12050 times
If you want to test this restful service fromt the web you will call it with something like:
http://localhost:8080/rho/TEST92SM/TEST92ONs
restful02.jpg
restful02.jpg (228.31 KiB) Viewed 12050 times
Now, this simple web page shows you a datatable with the information consuming the restful api and allow you to change the fields in the screen (click the field you want to change, change the value, press enter). The actual PUT is performed in a server module (as suggested in the documentation).

Image

This is the web page:

Code: Select all

Begin_Com Role(*EXTENDS #PRIM_WEB) Theme(#SYS_THEME<MaterialDesignBlue>) Layoutmanager(#LayoutMain) Height(721)

Define_Com Class(#PRIM_TBLO) Name(#LayoutMain)
Define_Com Class(#PRIM_TBLO.Column) Name(#LayoutMainColumn1) Displayposition(1) Parent(#LayoutMain) Width(2)
Define_Com Class(#PRIM_TBLO.Column) Name(#LayoutMainColumn2) Displayposition(2) Parent(#LayoutMain) Width(20)
Define_Com Class(#PRIM_TBLO.Column) Name(#LayoutMainColumn3) Displayposition(3) Parent(#LayoutMain) Width(2)
Define_Com Class(#PRIM_TBLO.Row) Name(#LayoutMainRow1) Displayposition(1) Parent(#LayoutMain) Height(2)
Define_Com Class(#PRIM_TBLO.Row) Name(#LayoutMainRow2) Displayposition(2) Parent(#LayoutMain) Height(4.91)
Define_Com Class(#PRIM_TBLO.Row) Name(#LayoutMainRow3) Displayposition(3) Parent(#LayoutMain) Height(22.09)
Define_Com Class(#PRIM_TBLO.Item) Name(#LayoutMainItem1) Manage(#laTitle) Parent(#LayoutMain) Row(#LayoutMainRow1) Sizing(None) Column(#LayoutMainColumn2)
Define_Com Class(#PRIM_TBLO.Item) Name(#LayoutMainItem2) Manage(#Messages) Parent(#LayoutMain) Row(#LayoutMainRow2) Column(#LayoutMainColumn2) Marginbottom(10) Marginleft(10) Marginright(10) Margintop(10)
Define_Com Class(#PRIM_TBLO.Item) Name(#LayoutMainItem3) Manage(#TEST92ON) Parent(#LayoutMain) Row(#LayoutMainRow3) Column(#LayoutMainColumn2) Marginbottom(10) Marginleft(10) Marginright(10) Margintop(10)

Define_Com Class(#PRIM_LABL) Name(#laTitle) Caption('TEST92ON API') Displayposition(1) Ellipses(Word) Height(33) Left(476) Parent(#COM_OWNER) Tabposition(1) Tabstop(False) Top(9) Verticalalignment(Center) Width(249) Themedrawstyle('Title')
Define_Com Class(#PRIM_LIST) Name(#Messages) Displayposition(2) Left(110) Parent(#COM_OWNER) Tabposition(2) Top(60) Width(980) Height(102)
Define_Com Class(#PRIM_LIST.String) Name(#MessagesColumn1) Columnwidth(1) Displayposition(1) Parent(#Messages) Sortonclick(True) Source(#STD_QSEL) Columncaption('     Messages') Columncaptionalign(Left) Columncaptiontype(Caption) Columnunits(Proportion)

Define_Com Class(#PRIM_LIST) Name(#TEST92ON) Columnlines(False) Displayposition(3) Height(529) Left(110) Parent(#COM_OWNER) Tabposition(3) Top(182) Width(980) Columnheaderheight(48) Rowheight(48)
Define_Com Class(#PRIM_LIST.String) Name(#TEST92ON2Column1) Columnwidth(1) Displayposition(1) Parent(#TEST92ON) Sortonclick(True) Source(#EMPNO) Displayalignment(Right) Columnunits(Proportion)
Define_Com Class(#PRIM_LIST.String) Name(#TEST92ON2Column2) Columnwidth(2) Displayposition(2) Parent(#TEST92ON) Sortonclick(True) Source(#SURNAME) Columnreadonly(False) Columnunits(Proportion) Displayalignment(Center)
Define_Com Class(#PRIM_LIST.String) Name(#TEST92ON2Column3) Columnwidth(1) Displayposition(3) Parent(#TEST92ON) Sortonclick(True) Source(#GIVENAME) Columnunits(Proportion) Displayalignment(Center)
Define_Com Class(#PRIM_LIST.Number) Name(#TEST92ONColumn1) Columnwidth(1) Displayposition(4) Parent(#TEST92ON) Sortonclick(True) Source(#SALARY) Columnunits(Proportion) Displayalignment(Center)

Define_Com Class(#STD_INT) Name(#HttpStatus)

Evtroutine Handling(#Com_owner.Initialize)
Clr_List Named(#Messages)
#COM_OWNER.GetTEST92ON
Endroutine

Mthroutine Name(GetTEST92ON) Access(*PRIVATE)
Define_Com Class(#Prim_Web.HttpRequest) Name(#GetTEST92ON)
Define_Com Class(#prim_web.JsonElement) Name(#JRoot_Element) Reference(*DYNAMIC)
Define_Com Class(#PRIM_WEB.json) Name(#Json)
#GetTEST92ON.Url := ("/" + #partition + "/TEST92SM/TEST92ONs")
* #GetTEST92ON.Url += "?SearchString=" + #Search.Value
#STD_QSEL := *TIMEDATEC + ' - ' + "Contacting Server " + #GetTEST92ON.Url
Add_Entry To_List(#Messages)

#GetTEST92ON.ExecuteAsync

Evtroutine Handling(#GetTEST92ON.Completed)
Clr_List Named(#TEST92ON)
#HttpStatus := #GetTEST92ON.Response.StatusCode

#Json := #GetTEST92ON.Response.Content
#JRoot_Element <= #Json.RootItem

If (#HttpStatus <> 200)
#STD_QSEL := *TIMEDATEC + ' - ' + "Error Status Code: " + #HttpStatus.AsString + " Message: " + #GetTEST92ON.Response.StatusText + " received from server."
Add_Entry To_List(#Messages)
Else

For Each(#ArrayElem) In(#JRoot_Element)
For Each(#Entry) In(#ArrayElem)
Case (#Entry.Key)
When Value_Is(= "EMPNO")
#EMPNO := #Entry.AsString.Trim
When Value_Is(= "SURNAME")
#SURNAME := #Entry.AsString.Trim
When Value_Is(= "GIVENAME")
#GIVENAME := #Entry.AsString.Trim
When Value_Is(= "SALARY")
#SALARY := #Entry.AsString.Trim.AsNumber
Endcase
Endfor
Add_Entry To_List(#TEST92ON)
Endfor

#STD_QSEL := *TIMEDATEC + ' - ' + "Get TEST92ON completed successfully."
Add_Entry To_List(#Messages)
Endif

Endroutine

Evtroutine Handling(#GetTEST92ON.Failed)
#Sys_web.Alert Caption("Get TEST92ON Failed")
Endroutine

Endroutine

Evtroutine Handling(#TEST92ON2Column2.Enter)
#COM_OWNER.UpdateTEST92ON
Endroutine

Mthroutine Name(UpdateTEST92ON) Access(*PRIVATE)
Define_Com Class(#TEST92PUT.SendPUT) Name(#SendPUT)
Group_By Name(#Fields) Fields(#EMPNO #SURNAME #GIVENAME #SALARY)

#SendPut.Execute Fields(#Fields) Std_Qsel(#STD_QSEL)
Add_Entry To_List(#Messages)
Endroutine
End_Com
and this is the server module TEST92PUT that this web page is calling to update the record:

Code: Select all

Begin_Com Role(*EXTENDS #PRIM_SRVM)
Group_By Name(#Fields) Fields(#EMPNO #SURNAME #GIVENAME #SALARY)
Srvroutine Name(SendPUT)
Group_Map For(*INPUT) Group(#fields)
Field_Map For(*OUTPUT) Field(#STD_QSEL)

Define_Com Class(#XPrim_HttpRequest) Name(#Req)
Define_Com Class(#XPRIM_UriBuilder) Name(#Url)
Define_Com Class(#XPRIM_JsonObject) Name(#JsonObject)

#Url.SetScheme( 'http' )
#Url.SetHost( 'localhost:8080' )
#Url.SetPath( ("/" + #partition + "/TEST92SM/TEST92ONs/" + #EMPNO) )

#JsonObject.InsertString Key("EMPNO") String(#EMPNO)
#JsonObject.InsertString Key("SURNAME") String(#SURNAME)
#JsonObject.InsertString Key("GIVENAME") String(#GIVENAME)
#JsonObject.InsertNumber Key("SALARY") Number(#SALARY)

#Req.Content.AddJsonObject( #JsonObject )

* Execute the request (POST verb)

#Req.DoPut Url(#Url)

If (#Req.Response.IsSuccessfulRequest)
#STD_QSEL := #Req.Response.IsSuccessfulRequest
Else
#STD_QSEL := #Req.Response.ErrorCode.AsNativeString + ' ' + #Req.Response.ErrorMessage.AsNativeString
Endif
Endroutine
End_Com
*** You can use the attached template at your own risk, as-is, no warranty (nothing in life is guaranteed), it will help you create a web page (and the content for the "PUT server module" commented at the end, just because I have no idea how to create one of the fancy new templates that can create several objects in the repository and I didn't wanted to create two templates).

The answers given to the template for example in this case, were TEST92SM for the first question, TEST92ON for the second and PSLmini in the third. the template assumes the rest (even localhost:8080 so change that accordingly). The templates assumes you want to use all the fields in the file and that the first one is the identification.
QuickExport20210902170112consumingrestful.zip
(6.62 KiB) Downloaded 1053 times
Post Reply