Page 1 of 1

Consuming a webservice from a server side function on IBM i

Posted: Wed Jun 05, 2019 11:45 pm
by isk
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.

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

Posted: Thu Jun 06, 2019 6:09 am
by jyoung
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

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

Posted: Mon Jun 10, 2019 8:16 pm
by isk
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.

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

Posted: Tue Jun 11, 2019 12:26 am
by jyoung
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