I've the same problem reported in this question. https://community.appian.com/discussions/f/integrations/11905/integration-object---test-request---json-request-body-with-arrays
However, the solution does not solve my problem.
The request body expected by the API documentation is as follows (Request body 1). I tested this successfully using Postman with a response as described by the API. However, due to the ssquare brackets, this body is not accepted in Appian editor. When I replaced square brackets with curly braces, I get the error message as given below (Error 1). Then I changed the request body based on the solution to the above question link (Request body 2). And got Error described in Error 1 again. Can you please help with the correct way to construct this request body?
Request body 1:{ "Inputs": { "input1": { "ColumnNames": [ "vendor_id", "rate_code", "passenger_count", "trip_distance", "payment_type", "fare_amount" ], "Values": [ [ "CMT", "0", "0", "0", "CRD", "0" ], [ "CMT", "0", "0", "0", "CRD", "0" ] ] } }, "GlobalParameters": {} }Error 1:Error message in Appian after replacing square brackets with curly braces:Request body 2:a!toJson( { "Inputs": { "input1": { vendor_id: "CMT", rate_code: "0", passenger_count: 0, trip_distance: 0, payment_type: "CRD", fare_amount: 0 } } })Error 2:
The external system did not understand the request
The request was missing required details or was improperly formatted HTTP/1.1 400 Bad Request Next Steps
Discussion posts and replies are publicly visible
The reason this is happening is that you have a list of lists that aren't named parameters. Appian in general tries to avoid creating lists of lists because they are very difficult to index data out of - you will almost always see data created by Appian will flatten the lists to make it easier to use. However, this can result in some interesting behavior when you actually need a list of lists like you do in your "Values" parameter.
Here's what I'd suggest doing: start by seeing if you can send the exact text string above in request body too without putting it in as an expression or trying to cast to JSON. The easiest way to do this is to literally copy that text into a rule input that you directly pass into the request body like this:
Notice if I pass it in directly like this, then the request matches it exactly. If you get this to work correctly, then you know that the service is working correctly with this request, you just have to format it to get like this. Now if you're sending the exact same string every time, then you're done! But my assumption is that this data is coming from somewhere in Appian and you need to format it, so step 2 is to get the data into this format.
Appian's expression language is not the same as JSON (although it is close), so what I'd suggest next is trying to get this JSON into Appian's expression format. If you create an expression rule and do a!fromJson(ri!input) and copy the text into the input of your expression rule just like above, you will see what Appian expression corresponds to this.
However, if you try to copy this exact result into another expression rule, you will actually see that Appian flattens that array!
That means you have to do something else to get the data in the correct format. There are two ways I have seen to get this to work. The first is to use the type!Variant. The variant type is basically the same as the "Any Type" in Appian, so you can use it to create complex lists. So, you could restructure your expression to be something like this:
{ Inputs: { input1: { ColumnNames: { "vendor_id", "rate_code", "passenger_count", "trip_distance", "payment_type", "fare_amount" }, Values: { cast( type!Variant, { "CMT", "0", "0", "0", "CRD", "0" } ), cast( type!Variant, { "CMT", "0", "0", "0", "CRD", "0" } ) } } }, GlobalParameters: {} }
When you cast to Variant like this, it explicitly overrides Appian's default behavior of flattening the list, so you should get the correct output!
Your other option is to use a!forEach(). This function wraps the result in a list of variant automatically, so if you provide a list in the result of each item it won't flatten it. Now you would have to figure out the best way to set this up with your data, but I have a simple example using the Json you provided that works:
a!localVariables( local!list1: { "CMT", "0", "0", "0", "CRD", "0" }, local!list2: { "CMT", "0", "0", "0", "CRD", "0" }, { Inputs: { input1: { ColumnNames: { "vendor_id", "rate_code", "passenger_count", "trip_distance", "payment_type", "fare_amount" }, Values: { a!forEach( items: { 1, 2 }, expression: if( fv!index = 1, local!list1, local!list2 ) ), } } }, GlobalParameters: {} } )
Hope that helps and let me know if you have any further questions!
Thank you so much Peter. I tried the cast(type!Variant, {}) and it worked perfectly. Thanks again.
There is one more change that was needed to get it fully working (credit to Vuram Vimal Kumar, he helped with this) as below (GlobalParameters: {} wrapped within a!fromJson(). This avoided GlobalParameters: {} becoming GlobalParameters: [] )
a!toJson(
{ Inputs: { input1: { ColumnNames: { "vendor_id", "rate_code", "passenger_count", "trip_distance", "payment_type", "fare_amount" }, Values: { cast( type!Variant, { "CMT", "0", "0", "0", "CRD", "0" } ), cast( type!Variant, { "CMT", "0", "0", "0", "CRD", "0" } ) } } }, GlobalParameters: a!fromJson( "{}"
)}
)