Web API Wizard- receiving multiple requests in one structure
-
- Posts: 109
- Joined: Thu Feb 11, 2016 12:01 am
Web API Wizard- receiving multiple requests in one structure
Hello everybody,
I need to create an Web API that should receive the following structure:
How many such elements the request contains can vary from time to time.
How many such elements the request contains can vary from time to time.
I have in my Web API server module, which I created automatically using the LANSA wizard, a path /customer_price, which in turn has an operation Getcustomer_prices (verb=get).
Do I have to define anything in this operation to receive this structure? By default the parameter SearchString is created automatically.
And how do I process such a structure in the associated server routine Getcustomer_prices?
Unfortunately I can't find any hint in the documentation or LearnLANSA tutorials on how to implement this - and I have no idea how to handle this...
Many thanks in advance for your support,
Jörg
I need to create an Web API that should receive the following structure:
How many such elements the request contains can vary from time to time.
How many such elements the request contains can vary from time to time.
I have in my Web API server module, which I created automatically using the LANSA wizard, a path /customer_price, which in turn has an operation Getcustomer_prices (verb=get).
Do I have to define anything in this operation to receive this structure? By default the parameter SearchString is created automatically.
And how do I process such a structure in the associated server routine Getcustomer_prices?
Unfortunately I can't find any hint in the documentation or LearnLANSA tutorials on how to implement this - and I have no idea how to handle this...
Many thanks in advance for your support,
Jörg
Re: Web API Wizard- receiving multiple requests in one structure
You might struggle using the verb get because I think it doesn't allow for a request body. I think the wizard generates most of the RDMLX for the routine. The request also needs to be defined in the Path/Operations section within the request tab.
Re: Web API Wizard- receiving multiple requests in one structure
Further, if adding a request in after the wizard has done it's work you'll need to put in a Define_Com Class(#Com_Home.xxRequestTypeName) statement at the top of the server routine. xxRequestTypeName just being replaced by the name of your request as defined in Types. Then further down once in the If (#Operation.TryBind( #Context )) section of code a line needs to be added to use that defined component. This will be : Get Com(#Operation.Request.ContentJson) Com_Fields(#xxRequestTypeName).
Re: Web API Wizard- receiving multiple requests in one structure
Hi,
Let's try to do this together...
for simplicity (because you can also just go to schema and manually define it), I created first a simple table, called it cnrtable, with fields cnr, snr, sku and amount then a new server module from zero, and drag that table in Schema, which creates a cnrtableArray and a cnrtableObject.
Then create a couple of server routines, one to handle the status, and one to handle the getPricesOperation.
Went to the API definition tab, and filled all the marked things here with the exception of the Schema types which were the result of just draggin the table in the schema area... notice I need to use Post instead of Get (my first error when trying this) and be sure to fill the Identifier when needed:
then added this server routine, pretty basic first, to see if I can receive the array:
then went to postman, created an small json to test:
and yes I am receiving the array as you can see in the string I return as response.
Next post... processing each item of the array and return the total of the amount or maybe just another array with the prices
Let's try to do this together...
for simplicity (because you can also just go to schema and manually define it), I created first a simple table, called it cnrtable, with fields cnr, snr, sku and amount then a new server module from zero, and drag that table in Schema, which creates a cnrtableArray and a cnrtableObject.
Then create a couple of server routines, one to handle the status, and one to handle the getPricesOperation.
Went to the API definition tab, and filled all the marked things here with the exception of the Schema types which were the result of just draggin the table in the schema area... notice I need to use Post instead of Get (my first error when trying this) and be sure to fill the Identifier when needed:
then added this server routine, pretty basic first, to see if I can receive the array:
Code: Select all
Begin_Com Role(*EXTENDS #PRIM_SRVM)
Srvroutine Name(cnrRoutine) Response(*HTTP #http)
* Instance of the getPricesOperation. this #COM_Home.Status relates to API Definition, Operation Name
Define_Com Class(#Com_Home.getPricesOperation) Name(#Operation)
Define Field(#contentstring) Type(*Char) Length(256) Decimals(0)
Define_Com Class(#Com_Home.cnrtableArray) Name(#cnrtableArray)
Define_Com Class(#Com_Home.cnrtableObject) Name(#cnrtableObject)
If (#Operation.TryBind( #http ))
#std_strng := #Operation.Request.ContentJson.ToJsonString.AsNativeString
#contentstring := '{' + (10).AsUnicodeString + '"JobID": "' + *JOBNBR + '",' + (10).AsUnicodeString + '"ServerStatus": "OK",' + (10).AsUnicodeString + '"Count": "' + #std_strng + '}'
#Operation.Response.SetContentString( #contentstring )
Endif
Endroutine
Srvroutine Name(statusRoutine) Response(*HTTP #http)
endroutine
End_Com
Code: Select all
[{"cnr": 123456,
"snr": "00",
"sku": "1531058",
"amount": 12},
{"cnr": 123456,
"snr": "00",
"sku": "1531058",
"amount": 11},
{"cnr": 123456,
"snr": "00",
"sku": "1531058",
"amount": 10}]
Next post... processing each item of the array and return the total of the amount or maybe just another array with the prices
Last edited by Dino on Wed Jul 27, 2022 12:38 am, edited 1 time in total.
Re: Web API Wizard- receiving multiple requests in one structure
Server routine changed to read the array and return the total of the amounts:
result is:
now if you want to return a json instead of a string, it's time to change the api definition, adding another schema with more fields to respond (or even reuse the same one and expand it), and probably a fetch inside this begin_loop to start preparing the response with basically fetch and add_entry following the same steps as the typical server module that responds with the list of all records, converting the list in an array.
Code: Select all
Srvroutine Name(cnrRoutine) Response(*HTTP #http)
* Instance of the Status Operation.. this #COM_Home.Status relates to API Definition, Operation Name
Define_Com Class(#Com_Home.getPricesOperation) Name(#Operation)
Define Field(#contentstring) Reffld(#VF_ELTXTX)
Define_Com Class(#XPRIM_RandomAccessJsonReader) Name(#Reader) Reference(*Deferred)
Define_Com Class(#XPRIM_ErrorInfo) Name(#ErrorObject) Reference(*Deferred)
Define_Com Class(#PRIM_BOLN) Name(#Found)
If (#Operation.TryBind( #http ))
#VF_ELTXTX := #Operation.Request.ContentJson.ToJsonString.AsNativeString
#Reader.SetSourceString String(#VF_ELTXTX) ErrorInfo(#ErrorObject)
#Reader.BeginArrayWithPath Path('/') Found(#Found)
#std_amnt := 0
Begin_Loop Using(#STD_NUM) To(#Reader.GetChildCount)
#Reader.BeginObjectAtIndex Index(#STD_NUM) Found(#Found)
If (#Found)
#cnr := #Reader.ReadNumberWithName( 'cnr' )
#snr := #Reader.ReadStringWithName( 'snr' ).AsNativeString
#sku := #Reader.ReadStringWithName( 'sku' ).AsNativeString
#amount := #Reader.ReadNumberWithName( 'amount' )
#std_amnt += #amount
#Reader.EndObject
Endif
End_Loop
#Reader.EndArray
#std_strng := #std_count.AsString
#contentstring := '{' + (10).AsUnicodeString + '"JobID": "' + *JOBNBR + '",' + (10).AsUnicodeString + '"ServerStatus": "OK",' + (10).AsUnicodeString + '"Count": "' + #Reader.GetChildCount.AsString + '",' + (10).AsUnicodeString + '"Total Amount":' + #std_amnt.AsString + (10).AsUnicodeString + '}'
#Operation.Response.SetContentString( #contentstring )
Endif
Endroutine
Code: Select all
{
"JobID": "013016",
"ServerStatus": "OK",
"Count": "3",
"Total Amount":33.00
}
-
- Posts: 109
- Joined: Thu Feb 11, 2016 12:01 am
Re: Web API Wizard- receiving multiple requests in one structure
Hi Dino, hi Catt,
thank you very much for your help!
This is a great description! Now I understand the interaction of the individual parts.
I now also got it working with the array response.
Best regards,
Jörg
thank you very much for your help!
This is a great description! Now I understand the interaction of the individual parts.
I now also got it working with the array response.
Best regards,
Jörg
Re: Web API Wizard- receiving multiple requests in one structure
Hi guys
While the code in this post still works, I would have thought that something like other code should work instead today but I cannot make it work... I guess I am missing something here.
While the code in this post still works, I would have thought that something like other code should work instead today but I cannot make it work... I guess I am missing something here.
Code: Select all
Define_Com Class(#Com_Home.cnrtableArray) Name(#cnrtableArray)
...
Get Com(#Operation.Request.ContentJson.cnrtableArray) Com_Fields(#cnrtableArray)
...
selectlist #cnrtableArray
...
endselect
- MARCOREMMEDATA
- Posts: 8
- Joined: Mon Apr 11, 2022 4:48 pm
- Location: ITALIA
- Contact:
Re: Web API Wizard- receiving multiple requests in one structure
Thank you for this article, it solved a problem for me. I share the solution to access an array within an array element
This is the Json
this the source
This is the Json
Code: Select all
[
{
"cnr": 123456,
"snr": "00",
"sku": "1531058",
"amount": 12,
"tag": [
{
"a1": 5,
"a2": 7
}
]
},
{
"cnr": 123456,
"snr": "00",
"sku": "1531058",
"amount": 11,
"tag": [
{
"a1": 3,
"a2": 4
}
]
},
{
"cnr": 123456,
"snr": "00",
"sku": "1531058",
"amount": 10,
"tag": [
{
"a1": 6,
"a2": 7
}
]
}
]
this the source
Code: Select all
DEFINE_COM CLASS(£XPRIM_RandomAccessJsonReader) NAME(£Reader)
DEFINE_COM CLASS(£XPRIM_ErrorInfo) NAME(£Error)
DEFINE_COM CLASS(£PRIM_BOLN) NAME(£Found)
DEFINE FIELD(£cnr) TYPE(*DEC) LENGTH(10) DECIMALS(3)
DEFINE FIELD(£SNR) TYPE(*CHAR) LENGTH(20)
DEFINE FIELD(£sku) TYPE(*CHAR) LENGTH(20)
DEFINE FIELD(£amount) TYPE(*DEC) LENGTH(10) DECIMALS(3)
DEFINE FIELD(£a1) TYPE(*DEC) LENGTH(1) DECIMALS(0)
DEFINE FIELD(£a2) TYPE(*DEC) LENGTH(1) DECIMALS(0)
DEFINE FIELD(£cnt1) TYPE(*DEC) LENGTH(5) DECIMALS(0)
DEFINE FIELD(£cnt2) TYPE(*DEC) LENGTH(5) DECIMALS(0)
DEFINE FIELD(£id1) TYPE(*DEC) LENGTH(5) DECIMALS(0)
DEFINE FIELD(£id2) TYPE(*DEC) LENGTH(5) DECIMALS(0)
£Reader.SetSourceString STRING('[{"cnr":123,"snr":"AA","sku":"SKU_1","amount":12,"tag":[{"a1":1,"a2":2},{"a1":3,"a2":4}]},{"cnr":456,"snr":"BB","sku":"SKU_2","amount":11,"tag":[{"a1":5,"a2":6}]},{"cnr":789,"snr":"CC","sku":"SKU_3","amount":10,"tag":[{"a1":7,"a2":8}]}]') ERRORINFO(£Error)
£Reader.BeginArrayWithPath PATH('/') FOUND(£Found)
£std_amnt := 0
£cnt1 := £Reader.GetChildCount
BEGIN_LOOP USING(£id1) TO(£cnt1)
£Reader.BeginObjectAtIndex INDEX(£id1) FOUND(£Found)
IF (£Found)
£cnr := £Reader.ReadNumberWithName( 'cnr' )
£snr := £Reader.ReadStringWithName( 'snr' ).AsNativeString
£sku := £Reader.ReadStringWithName( 'sku' ).AsNativeString
£amount := £Reader.ReadNumberWithName( 'amount' )
£Reader.BeginArrayWithPath PATH("/tag") FOUND(£Found)
IF (£Found)
£cnt2 := £Reader.GetChildCount
BEGIN_LOOP USING(£id2) TO(£cnt2)
£Reader.BeginObjectAtIndex INDEX(£id2) FOUND(£Found)
IF (£Found)
£a1 := £Reader.ReadNumberWithName( 'a1' )
£a2 := £Reader.ReadNumberWithName( 'a2' )
£Reader.EndObject
ENDIF
END_LOOP
£Reader.EndArray
ENDIF
£std_amnt += £amount
£Reader.EndObject
ENDIF
END_LOOP
£Reader.EndArray
MARCO ROSSI | Software Developer Sr. - Software Production