Logic Apps: JSON Parsing

The parsing of JSON in Azure Logic Apps is mysterious. I'm aiming to share what I've found with you and make your engineering day a lot more smoother...

Parsing JSON in Azure Logic Apps
The mystery of parsing JSON!

Years on and I still scratch my head wondering how to parse JSON data in Azure Logic Apps. Today I've spent some time working it out again and I'll document it here and I hope it helps you.

First off

JSON isn't easy to look at. Make it VISUAL. I'm using Visual Studio Code (it's free) and the extension "JSON Crack" (also free).

Before I visualised JSON in this, it was very difficult to figure out the levels of nested JSON. This will change your life. Trust me.

JSON Crack will make life easier for you
JSON Crack in Visual Studio Code
Instant visualisation of your JSON schema
Instant visualisation of your JSON schema

Challenges in Logic Apps

In some cases you can map a dynamic entity from one of your previous steps that is outputing the JSON. This isn't the case right now for me and as you will have probably come across before, logic apps will sometimes put an action inside a loop and then after adding some more dynamic mapping, it adds another loop then another loop.

The nesting continues....

This is hugely inefficient and isn't logical in most cases. See the screenshot below, there is no need for this to be in another loop as it's already in one.

The method I'm about to reveal below will avoid this.

The classic nested For each loops
The classic nested For each loops

Parse JSON Data Operation

I'm assumming right now, you've already got a JSON output from some previous action. Here I'm using the parse JSON data operation action in logic apps and have already specified the schema. Maybe I will explain this in another post.

Right now I will focus on the expression to retrieve the data we need.

Logic apps - Parse data operation

Complex JSON Data Structures

It can get more complex than this, but for some this is complex enough and this is what I'm working on right this minute.

Complex JSON structures

Let's use the example of accessing the object "fqdn" here which would contain a host name in the real world (redacted data).

We can easily see now it's visual, that the path to our data is body > hostStates > fqdn.

Expressions

Let's focus on the "set variable" action here in my logic.

This is where I want to parse FQDN into so I can use this data elsewhere.

Logic apps variable

If we view the config for the variable we can see where to specify it's value.

Logic apps variable value

Here we want to add a "Function". You will also see this written as "fx". This is where we create the expression to pull direct object we are looking for in the JSON.

Logic apps functions

The Key Part - Retrieving the JSON Object

I will try and make this as simple as possible.

If you remember the path to our data is body > hostStates > fqdn

We need to call on the previous action here, the action that is outputting our JSON and in this case it's called "Parse Graph API Response" but you will notice in the code view that it adds underscores. To call it, you will need to add the undercores.

body('Parse_Graph_API_Response')

Reaching hostStates would be easy.

This would dump all the other objects/indexes though and in some cases would work, but here we want to grab one object.

body('Parse_Graph_API_Response')['body']['hostStates']

hostStates contains a number of "indexes".

These indexes have a value and start here from the top as [0] through to [8]. The index does not start at [1].

JSON indexes

Simply, now we have stated "hostStates" in our expression, we now need to specify the index [0] (with no single quotes).

We still must specify the name of the object so this is then followed by ['fqdn'].

body('Parse_Graph_API_Response')['body']['hostStates'][0]['fqdn']

Hit update to save it. If you click anywhere else it won't save!

Checking Output

Assuming you know the next steps to get the data flowing and push the JSON into your action, let's now check it.

Checking output

The variable is now set with the hostname I need and I'm not stuck in unneeded nested loops by trying to use dynamic mapping!