I have got an assign message like below:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="am-set-request">
<DisplayName>am-set-request</DisplayName>
<Properties/>
<Set>
<Headers>
<Header name="api-key">{apikeyVar}</Header>
<Header name="Content-Type">application/x-www-form-urlencoded</Header>
</Headers>
<QueryParams>
<QueryParam name="abd">{abdVar}</QueryParam>
<QueryParam name="abc">{abcVar}</QueryParam>
</QueryParams>
<FormParams>
<FormParam name="Payload">{request.content}</FormParam>
</FormParams>
</Set>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
but when I get a payload like below:
{
"ABC": {
"message": {
"origin": "",
},
"response": {
"messages": [
{
"messageId": "message123",
"message": "<ns0:ABC xmlns:ns0=\"urn:example.com:fin:12345:CUST\"><Tag0> <Tag1>12344</Tag1> <Tag2>B123456</Tag2> <Tag3/> <Tag4/> <Tag5>44444</Tag5> </Tag0></ns0:ABC>"
}
]
}
}
}
the apigee confuses the = sign and assumes there are 2 formparams. I had to use a workaround like below to resolve this:
context.setVariable("request.formparam.Payload",JSON.stringify(JSON.parse(context.getVariable("request.content"))));
Is there some better solution for this? or is the Payload formparam assignment in the AM policy wrong?
Thanks in advance.
Solved! Go to Solution.
hmmm
what I understand you're doing:
request.content
), which is json, and use that as the value for a single form parameter. Essentially replacing the json content with form content.is that about right?
And also, the JSON actually wraps some XML!! Amazing! XML, wrapped in JSON, then encoded as a form param. (If there were an award for using the most data formats in one message, you would win!)
What you're doing is ... unorthodox. A little bit unique. First question: Are you sure you want to do it that way? If I were an architect on a project , in which someone proposed doing this, I would ... ask that person to re-consider. The issue you're running into is just ONE of the reasons why it's probably not the best idea.
I tried what you tried, and it MOSTLY works. In fact I don't see a problem with the equals sign at all. You said "the apigee confuses the = sign and assumes there are 2 formparams." but that is a conclusion, not an observation. What did you observe that lead you to the conclusion that "apigee is confused"? My observation shows that the form param gets appropriately set. Subsequent to the AssignMessage, my request body looks like this:
Payload=%7B%20%20%22ABC%22%3A%20%7B%20%20%20%20%22message%22...
...which looks correct to me. All the stuff after the equals sign is an encoded JSON payload.
But there is one nuance. One thing I had to change. By using the Set element in AssignMessage, you are setting the content-type and setting the formparam. But you haven't removed the original json content. So there is still a JSON body on the message. You need to remove the original content, and then set the form param. You can remove the payload body within AssignMessage like this:
<AssignMessage continueOnError="false" enabled="true" name="AM-Transform-Message">
...
<Remove>
<Payload/>
</Remove>
But removing the original content means it will no longer be available in the variable request.content
. request.content
will return the empty string. So you need to save the original content in a different variable, then remove it, then set the form param. like this:
<AssignMessage name="AM-Transform-Message">
<AssignVariable>
<Name>retained-payload</Name>
<Ref>request.content</Ref>
</AssignVariable>
<Remove>
<Payload/>
</Remove>
<Set>
<Headers>
<Header name="api-key">{apikeyVar}</Header>
<Header name="Content-Type">application/x-www-form-urlencoded</Header>
</Headers>
<QueryParams>
<QueryParam name="abd">{abdVar}</QueryParam>
<QueryParam name="abc">{abcVar}</QueryParam>
</QueryParams>
<FormParams>
<FormParam name="Payload">{retained-payload}</FormParam>
</FormParams>
</Set>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<!--
OMIT THIS. IT DOES NOTHING.
<AssignTo createNew="false" transport="http" type="request"/>
-->
</AssignMessage>