Retrieving API request body

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
Catt
Posts: 2
Joined: Mon Jun 10, 2019 8:00 pm

Retrieving API request body

Post by Catt » Mon Jun 10, 2019 8:09 pm

Currently creating a web API for publishing, however having issues coding to access the request body. At present I have the response defined in the server routine definition like : Srvroutine Name(APItut4) Response(*HTTP #uoHTTP4)

I've tried using variations of the .request.content intrinsic on #uoHTTP4, however can't seem to get anything working. Has anyone else had any luck being able to access (and process) the body from a request?

Thanks

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

Re: Retrieving API request body

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

If you are trying to read the body of a request, and its JSON, you can use the PRIM_JSON_Document.

Here is an example of reading POSTDATA from a request. The POSTDATA contains an array of "links".
Note the APIContext seen here is a helper class that formats the proper response codes and messages.

Code: Select all

define_map for(*INPUT) class(#PRIM_SRVM.HttpContext) name(#pContext) pass(*BY_REFERENCE)
define_com class(#PRIM_JSON.Document) name(#lDocument)
define_com class(#PRIM_JSON.Object) name(#lRequestObject) reference(*DYNAMIC)
define_com class(#PRIM_JSON.Member) name(#lRequestMember) reference(*DYNAMIC)
define_com class(#PRIM_JSON.Array) name(#lLinks) reference(*DYNAMIC)

define_com class(#PRIM_ACOL<#PRIM_ALPH>) name(#lMessages)

if (#pContext.Request.PathParameters.TryParseAsInt32( "wcn" #wk_WebControlNumber ) = False)
    #APIContext.BadRequest( #pContext "Missing Web Control Number" )
    return
endif

if (#wk_WebControlNumber = 0)
    #APIContext.BadRequest( #pContext "Invalid Web Control Number" )
    return
endif

#lDocument.LoadFromString( #pContext.Request.Content.FormVariables<"*POSTDATA">.GetText )

if (#lDocument.RootNode.IsNull)
    * no data in request body
    #APIContext.BadRequest( #pContext "Missing Request Body" )
    return
endif

* convert the root node to a json object
#lRequestObject <= #lDocument.RootNode *As #PRIM_JSON.Object

if (#lRequestObject *Is *NULL)
    * could not convert document to json
    #APIContext.BadRequest( #pContext "Could not convert Document to JSON" )
    return
endif

* now we can get the links member
#lRequestMember <= #lRequestObject<'Links'> *As #PRIM_JSON.Member

if (#lRequestMember *Is *NULL)
    * could not get links node from json 
    #APIContext.BadRequest( #pContext "Could not get links from JSON" )
    return
endif

* if the member is an array, we can 'cast' that member to an array
if ((#lRequestMember *IsNot *NULL) *AndIf (#lRequestMember.IsArray))
    #lLinks <= #lRequestMember.Value *As #PRIM_JSON.Array
else
    * missing links arrary in request body
    #APIContext.BadRequest( #pContext "Missing Links Array in Request Body" )
    return
endif


for each(#lLink) in(#lLinks)
    * do work with the links
endfor

* we're done
#APIContext.Ok( #pContext )
Hope this helps,
Joe

Catt
Posts: 2
Joined: Mon Jun 10, 2019 8:00 pm

Re: Retrieving API request body

Post by Catt » Thu Jun 20, 2019 6:00 pm

Thank you :)

soa
Posts: 280
Joined: Mon Dec 07, 2015 3:15 pm

Re: Retrieving API request body

Post by soa » Wed Jul 03, 2019 12:13 pm

Hi

I have a piece of json that looks like

[{"id":6378787,"test_session":221568,"test_item":368,"response":"\"1\"","full_response":"1","correct":false,"time_taken":49.3727610111237,"modified":false,"flags":0,"flags_detailed":"{}"},{"id":6379123,"test_session":221568,"test_item":3985,"response":"\"4\"","full_response":"4","correct":false,"time_taken":53.1551909446716,"modified":false,"flags":0,"flags_detailed":"{}"},{"id":6379284,"test_session":221568,"test_item":3424,"response":"\"2\"","full_response":"2","correct":true,"time_taken":26.8898990154266,"modified":false,"flags":0,"flags_detailed":"{}"},

It contains an unnamed array. I'm using the code above to read it.

Define_Com Class(#PRIM_JSON.Document) Name(#lDocument)
Define_Com Class(#PRIM_JSON.Object) Name(#lRequestObject) Reference(*DYNAMIC)
Define_Com Class(#PRIM_JSON.Member) Name(#lRequestMember) Reference(*DYNAMIC)
Define_Com Class(#PRIM_JSON.Array) Name(#lLinks) Reference(*DYNAMIC)

1. #UniCodeString := #Request.Response.AsString
2. #lRequestObject <= #lDocument.RootNode *As #PRIM_JSON.Object

3. #lRequestMember <= #lRequestObject<'Links'> *As #PRIM_JSON.Member
4. #lLinks <= #lRequestMember.Value *As #PRIM_JSON.Array

but I can't get past step 3 as I don't have an object name and thus can't turn the Object Into member.

Any ideas?

tsupartono
Posts: 74
Joined: Wed Jan 25, 2017 11:12 am

Re: Retrieving API request body

Post by tsupartono » Wed Jul 03, 2019 12:55 pm

Your #Document.RootNode is an array, so you can just iterate through it

Code: Select all

For Each(#Child) In(#Document.RootNode)
	#STD_INT := #Child<'id'>.AsInt32
Endfor

soa
Posts: 280
Joined: Mon Dec 07, 2015 3:15 pm

Re: Retrieving API request body

Post by soa » Wed Jul 03, 2019 2:37 pm

That's awesome

In the example above

[{"id":6378787,"test_session":221568,"test_item":368,"response":"\"1\"","full_response":"1","correct":false,"time_taken":49.3727610111237,"modified":false,"flags":0,"flags_detailed":"{}"},

I can't get the value "time_taken"

I've tried asDecimal and asString and there isn't an asFloat.

I recall from another post that there was an issue with asDecimal so is this not possible at this stage?

tsupartono
Posts: 74
Joined: Wed Jan 25, 2017 11:12 am

Re: Retrieving API request body

Post by tsupartono » Wed Jul 03, 2019 3:07 pm

Yes - the upcoming EPC 142060 should fix the issue.

Post Reply