Ive seen lots of Logic Apps where there is a lot of logic trying to convert the response from an API into something more user friendly to be able to use the data in the logic of your workflow. One of the common examples is I call an API to get a single record but the system always returns a search with an array but I know I will always only get one item back.

These Logic Apps then often have various expression approaches to extract the data you need.

If your using APIM to centralize your API usage then there is an easy way you can use the APIM policy to manipulate the data which will then make your logic app a lot simpler.

Lets take an example where the API returns the below response message. I need to extract the first item in the array (even though I know there will always be one record) and then I need to extract the various fields.

{
  "businessObjects": [
    {
      "busObId": "ID",      
      "fields": [        
        {
          "displayName": "Created Date Time",          
          "name": "CreatedDateTime",
          "value": "5/6/2022 7:01:07 AM"
        },
        {
          "displayName": "Last Modified Date Time",          
          "name": "LastModDateTime",
          "value": "5/6/2022 9:17:42 AM"
        },
        {
          "displayName": "Full name",          
          "name": "FullName",
          "value": "TBC"
        }
      ]      
    }
  ]
}

The first thing I can do is to use an outbound policy like below which will extract the first item in the array so in my Logic App I will get an object rather than the array.

<outbound>
        <base />
        
        <set-body template="liquid">
            {{body.businessObjects | first }}
        </set-body>
    </outbound>

This will change the message the logic app gets to look like this.

{
    "busObId": "ID",      
    "fields": [        
      {
        "displayName": "Created Date Time",          
        "name": "CreatedDateTime",
        "value": "5/6/2022 7:01:07 AM"
      },
      {
        "displayName": "Last Modified Date Time",          
        "name": "LastModDateTime",
        "value": "5/6/2022 9:17:42 AM"
      },
      {
        "displayName": "Full name",          
        "name": "FullName",
        "value": "TBC"
      }
    ]      
  }

At this point things are a little simpler but I can do more. I can modify the policy in APIM to be like below.

<outbound>
        <base />
        
        
        <set-body template="liquid">
            {{body.businessObjects | first }}
        </set-body>

        <set-body template="liquid">
        {    
            "busObjId":"{{body.busObId}}",                              
            {% for field in body.fields %}
                    "{{field.name}}" : "{{field.value}}"{%- if forloop.last %}{% else %},{% endif %}
            {% endfor %}                                
        }
        </set-body>
    </outbound>

This will flatten the array of fields and give me a json object like below.

{
      "busObId": "ID", 
      "CreatedDateTime":"5/6/2022 7:01:07 AM",    
      "LastModDateTime":"5/6/2022 9:17:42 AM",
      "FullName":"TBC"
  }

In my logic app I will now just be able to use a simple parse json and get on with developing the logic rather than having write nasty expressions and logic to extract data from the message.

If your coming from a BizTalk background this approach is a bit like how you would have had a map on your send port where it is abstracting some data transformation from the orchestration logic. The APIM policy with a liquid template is playing the same role as the map and I have just made my Logic App significantly simpler which we always like.

 

Buy Me A Coffee