One of the key components of an integration platform is message translation. The Microsoft Azure iPaaS Logic Apps service offers message translation with the out of the box ‘compose’ operation. Alternatively, message translation can be achieved with Liquid transforms. The latter requires an Azure Integration account which comes with additional cost. In this article we’ll look at the two transformation options and do a comparison in terms of cost, performance and usability. For my demo purposes I created two logic apps with HTTP input triggers and response output.
Performance
For the purpose of testing the performance of Logic App execution, I generated a sample JSON payload on https://www.json-generator.com/ containing an array of 1500 objects with a payload of about 1MB.
Although you can increase the compose performance by increasing the degree of parallelism of your for-each loop, the Liquid transform performs significantly better in all cases.
Input payload | Liquid | Compose |
800KB array with 1500 items | 1.5 seconds | 12 seconds |
1.6MB array with 3000 items | 3 seconds | 22 seconds |
Needless to say, if you’re working with large arrays of data and performance is a criteria, Liquid maps are the way to go.
Winner: Liquid
Cost
For development scenarios you can use a free tier, which comes without an SLA and limitations around the maximum number of maps (25) and instances (1 account per region).
For production scenarios you have the choice of either a basic or standard account. The main difference between the two is the number of EDI partners and agreements that can be setup, which has no relevance to message translation scenarios. A basic integration account falls just short of $400 AUD a month but allows 500 maps to be created. Execution is still charged at the price of a standard action, so there’s no additional cost over the JSON compose transformation. In fact, the cost of the JSON compose solution could rapidly increase due to the for-each construct that’s needed to iterate through an array. If you’re mapping large sets of arrays at a frequent basis you may even come close to justifying the integration account from a cost perspective.
Winner: Compose
Assembly
JSON Compose
Compose mappings can be created directly in the Logic App designer. The compose editor is a bit fiddly and flaky in both browser as well as VS2017 and I found myself reverting to the code editor at times. Overall it’s fairly easy to construct basic mappings.
Liquid transforms
Liquid transforms can be easily created in your text editor of choice. Visual Studio Code has some nice extensions that given you snippets or even output preview.
[ {% for item in content %} { "Id": "{{ item._id }}", "Name": "{{ item.name }}", "Email": "{{ item.email }}", "Phone": "{{ item.phone }}", "Address": "{{ item.address }}", "About": "{{ item.about }}", }, {% endfor %} ]
Winner: tie
Deployment
Liquid transforms are managed and deployed separately from your Logic Apps, greatly enhancing the ability to reuse maps. Although easy to upload or update in the Azure Portal, in CI/CD pipelines you’ll find yourself writing separate PowerShell scripts in addition to your Logic App ARM templates.
Compose transformations are deployed as part of your Logic Apps, and therefore can be deployed as part of the Logic App ARM templates.
Winner: Compose
Conclusion
Whether to use Liquid transforms or Compose largely comes down to your own needs around performance, cost and mapping complexity required (e.g. nested loops, this can get ugly with Compose). If you require transformations involving XML you’ve got another strong argument for Liquid maps. When doing enterprise integration at scale there’s probably no way around needing Liquid maps and with the ability to create up to 500 maps per integration account cost can be shared amongst many integrations.
Nice!
Another cheap option for complex mappings is to add a pure simple input-output Azure Function. It won’t be as fast as Liquid templates but it is far more easy to debug than the Compose action.
It can’t be deployed using ARM templates. You would have to configure a separate App Service deployment. I often end up adding a Function App to a Logic App project anyway.
Indeed, Azure Functions are a great option if you want to perform certain mapping logic or execute business rules. But like you mention it comes with the additional overhead of having to manage another resource and additional code.