Consuming a webservice from a server side function on IBM i

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
isk
Posts: 2
Joined: Wed Jun 05, 2019 11:33 pm

Consuming a webservice from a server side function on IBM i

Post by isk » Wed Jun 05, 2019 11:45 pm

Hi, does anyone have any experience consuming webservices or making RESTful requests from a server side function on IBM i? I can only find documentation for the XPRIM_HttpRequest (https://docs.lansa.com/14/en/lansa018/c ... _begin.htm) but it is unclear how this is used within a server side function. Thanks.

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

Re: Consuming a webservice from a server side function on IBM i

Post by jyoung » Thu Jun 06, 2019 6:09 am

Are you referring to executing from an actual Function (ie. in a Process) or just executing from a server side component?

I've done it using XPRIM_HTTPRequest wrapped in a Server Side Reusable Part which is called from the Server Module. I assume the same would work inside a Function.

Regarding the XPRIM_HTTPRequest, there still is not a lot of documentation on it. The link you found is pretty much it. There have been some questions on the forums about it, with which I have been able to piece together our implementation.

The tricky part is reading the response as the XPRIM_JSONReader performs very poorly on the iSeries with large JSON docs. See this post for more info. viewtopic.php?f=4&t=2047&p=5403

Make sure you take a look at "Working With JSON Data" at https://docs.lansa.com/14/en/lansa018/i ... a%7C_____0

Checkout this post too regarding reading arrays. viewtopic.php?f=3&t=1499 I ended up having to use this technique to read the arrays from the response.

Which turned into something like this

Code: Select all


#lRequest.DoGet( #lUrl )

if ((#lRequest.Response.IsSuccessfulRequest) *AndIf (#lRequest.Response.IsSuccessHttpStatusCode))

#lReader.SetSourceHttpResponse httpresponse(#lRequest.Response)

#lReader.ReadBeginArray found(#lOk)
#lReader.MoveNext ok(#lOk)

dowhile (#lOk *And (*Not #lReader.IsEndArray))
#lReader.ReadObject found(#lOk) result(#lObject)
#lReader.MoveNext ok(#lOk)

* do stuff with the #lObject

endwhile

#lReader.ReadEndArray

if (*Not #lOk)
* something went wrong reading the response
#pMessages.Insert( (*New #PRIM_ALPH) )
#pMessages.Last := ("Could not read response from &1").Substitute( #lUrl )
return
endif

else
#lRequest.Response.ErrorCode #lRequest.Response.ErrorMessage )
#pMessages.Insert( (*New #PRIM_ALPH) )
#pMessages.Last := ("Request to &1 Failed. Status: &2, ErrorCode: &3, ErrorMessage: &4").Substitute( #lUrl #lRequest.Response.HttpStatusCode.AsString #lRequest.Response.ErrorCode #lRequest.Response.ErrorMessage )
return
endif

Hope this helps.
Joe

isk
Posts: 2
Joined: Wed Jun 05, 2019 11:33 pm

Re: Consuming a webservice from a server side function on IBM i

Post by isk » Mon Jun 10, 2019 8:16 pm

Thanks for the info Joe. I need this to work from within a legacy function in a batch process on the IBM i. I can't get my head around how this could be possible from a function and the docs are too thin to be useful.

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

Re: Consuming a webservice from a server side function on IBM i

Post by jyoung » Tue Jun 11, 2019 12:26 am

I may be missing something specific to your scenario, but you can use XPRIM_HttpRequest from a Function. I have not tried on the IBM i in a batch process, but I don't see why it would not work.

This is Function that makes a simple HTTP request to Google and I get the response back.

Code: Select all

function options(*DIRECT)

define_com class(#ServerTraceHandler) name(#FunctionTraceHandler) scope(*APPLICATION)

#SYS_APPLN.TraceMessageData( "This is a Trace Message from a Function" )

#COM_OWNER.TestRequest

return

mthroutine name(TestRequest)
define_com class(#XPRIM_HttpRequest) name(#Request)
define_com class(#PRIM_DC.UnicodeString) name(#ResponseText)

* Do the get request
#Request.DoGet url('http://wwww.google.com')

* Get the result as string
#ResponseText := #Request.Response.AsString

#SYS_APPLN.TraceMessageText( #ResponseText.AsNativeString )
endroutine
I'm not by any means an iSeries expert but I know there a few on these forums.
If you post the error you are getting and perhaps the joblog maybe they could help you out.

Joe

Post Reply