Since it was created, the AssignVariable element within the AssignMessage policy could be used to assign either a specific value to a variable, or to copy a value from one variable to another. The syntax looks like this:
<AssignMessage name='AM-1'>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<AssignVariable>
<Name>my_destination_variable</Name>
<Ref>request.queryparam.client_id</Ref>
<Value>BADDBEEF</Value>
</AssignVariable>
</AssignMessage>
This is useful when assigning a default value, in the case that a backing store does not have a value. For example, do a cache lookup, and then use an AssignMessage policy like the above to do this:
- if the value has been read from cache, assign THAT value to the variable.
- if the value has not been read from cache, assign a default value to the variable.
The AssignVariable with Ref/Value works for this purpose, but is pretty limited.
Sometimes people would like to be able to assign the result of a message template, into a variable. With the expansion of the set of available template functions with things like substring() and jsonPath(), this becomes even more interesting, and may allow people to avoid the use of some JavaScript policies. Because AssignVariable didn’t allow templates, people adopted a technique of creating a new message, and setting the message Payload, then assigning the message payload into a variable. As suggested here by Siddharth, this technique looks like this:
<AssignMessage name="Assign-Message-1">
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew='true' transport='http' type='request'>contrivedMessage</AssignTo>
<Set>
<Payload contentType="application/json">{
"system_timestamp": "{year}-{month}-{day}T{hour}:{minute}:{second}{millisecond}Z",
"TransactionId": "{TransactionId}"
}</Payload>
</Set>
<AssignVariable>
<Name>destination_variable</Name>
<Ref>contrivedMessage.content</Ref>
</AssignVariable>
</AssignMessage>
This works but is kludgy because you need to create an extraneous Message object in your proxy flow.
The desire to assign to a variable directly via a message template, is common enough that we wanted to support it directly. And now you can! the syntax looks like this:
<AssignMessage name='AM-1'>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<AssignVariable>
<Name>my_destination_variable</Name>
<Value>BADDBEEF</Value>
<Template>{system.uuid}-{messageid}</Template>
</AssignVariable>
</AssignMessage>
The Template child element under AssignVariable is new; it takes precedence over the other child elements.
For timestamps (which was the technical use case shown above), it’s even better. There are static functions available to format time strings. So you can do this:
<AssignMessage name='AM-1'>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<AssignVariable>
<Name>isoFormatString</Name>
<Value>yyyy-MM-dd'T'HH:mm'Z'</Value>
</AssignVariable>
<AssignVariable>
<Name>destination_variable</Name>
<Template>{timeFormatUTCMs(isoFormatString,system.timestamp)}</Template>
</AssignVariable>
<!-- example result: 2018-12-11T23:50Z -->
</AssignMessage>
I have a demonstration proxy here that provides examples of using this Template element, with all the message template functions in the AssignVariable element.
This has just launched, and the documentation has now been updated to describe this capability. We’re pretty excited about this; we think it will be super useful in many scenarios. I’d love to hear your feedback on these enhancements!