AssignMessage/AssignVariable now accepts a message template!

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!

Comments
mitchellarends
Bronze 5
Bronze 5

I just discovered this functionality within Apigee. It looks like a great addition for simple tasks that we would normally need to write a JavaScript for. One additional method that I think would be helpful would be a string length function. I have looked thru the documentation and haven't found one mentioned.

dchiesa1
Staff

Thanks for the feedback! We'll look into providing additional functions. Current list of desires: xpath, strlen.

sibijacob
New Member

Hi @Dino-at-Google, Recently came across this feature/post and we would be using in projects. Really helpful.

Would be really helpful if

1) We could check some conditions check in Assign Message policy, based on some input value.

2) Also if we define our own custom java functions and use them in the AssignMessage <Template>.

Will these features be made available?

Sibi

dchiesa1
Staff

Interesting ideas. We have JS policies for that kind of logic: conditions and your own custom functions.

I like the idea of defining custom functions. It's something we have been considering.

Thank you for the feedback.

Version history
Last update:
‎10-31-2018 09:37 AM
Updated by: