Saturday, February 29, 2020

Debatching(Splitting) JSON Message in Logic Apps - ForEach and SplitOn

Introduction

In last post Debatching(Splitting) XML Message in Logic Apps - ForEach and SplitOn we understood about Splitter pattern and how to use it to split/debatch messages.

In this post we will see how to debatch/split JSON message

Basic difference between XML (Extensible Markup Language) and JSON (JavaScript Object Notation) is - xml is a markup language and uses tag (that's why its heavier) structure to represent data items whereas JSON is a way of representing objects. 

JSON supports only UTF-8 encoding whereas XML supports many type of encoding


Steps to implement Splitter/Debatching Pattern in Logic App


Scenario : 


Say we want to debatch/split PurchaseOrders json message having multiple Purchase Order in it

{
"PurchaseOrders": {
"PurchaseOrder": [
{
"Address": [
{
"Name": "Ellen Adams",
"Street": "123 Maple Street",
"City": "Mill Valley",
"State": "CA",
"Zip": "10999",
"Country": "USA",
"_Type": "Shipping"
}
],
"DeliveryNotes": "Please leave packages in shed by driveway.",
"Items": {
"Item": [
{
"ProductName": "Lawnmower",
"Quantity": "1",
"USPrice": "148.95",
"Comment": "Confirm this is electric",
"_PartNumber": "872-AA"
},
{
"ProductName": "Baby Monitor",
"Quantity": "2",
"USPrice": "39.98",
"ShipDate": "1999-05-21",
"_PartNumber": "926-AA"
}
]
},
"_OrderDate": "1999-10-20",
"_PurchaseOrderNumber": "99503"
},
{
"Address": [
{
"Name": "Cristian Osorio",
"Street": "456 Main Street",
"City": "Buffalo",
"State": "NY",
"Zip": "98112",
"Country": "USA",
"_Type": "Shipping"
}
],
"DeliveryNotes": "Please notify me before shipping.",
"Items": {
"Item": {
"ProductName": "Power Supply",
"Quantity": "1",
"USPrice": "45.99",
"_PartNumber": "456-NM"
}
},
"_OrderDate": "1999-10-22",
"_PurchaseOrderNumber": "99505"
},
{
"Address": [
{
"Name": "Jessica Arnold",
"Street": "4055 Madison Ave",
"City": "Seattle",
"State": "WA",
"Zip": "98112",
"Country": "USA",
"_Type": "Shipping"
}
],
"Items": {
"Item": [
{
"ProductName": "Computer Keyboard",
"Quantity": "1",
"USPrice": "29.99",
"_PartNumber": "898-AZ"
},
{
"ProductName": "Wireless Mouse",
"Quantity": "1",
"USPrice": "14.99",
"_PartNumber": "898-AM"
}
]
},
"_OrderDate": "1999-10-22",
"_PurchaseOrderNumber": "99504"
}
]
}
}

Splitting using For each control


Create Http based Logic app 

In Azure portal create new instance of Logic App, once ready - in designer 

Add http trigger, followed by ForEach and Response Action
for each logic app

It is in For each control where we specify the path of the repeating node (which is to be splitted) 


adding expression in for each

triggerBody()['PurchaseOrders']['PurchaseOrder']

Using path above - we are asking to traverse through the triggerBody and look out of PurchaseOrder property and if found then add entry in  For each array.(All occurrence of PurchaseOrder property are added).

Now we add next steps within For each by using Add an action, here I have added Send an email step. So Send an email will be executed based on items in For each array, if there are 3 items then 3 times email will be sent out.

email action in for each

Note : The default behavior of For each loop is to run in parallel and each iteration in it runs in different
thread, however it can be made to run in sequential form by setting its Degree of Parallelism to 1.

Another example using For each debatching -- Inserting Multiple Records In On Prem SQL Using Logic App

Splitting using SplitOn property on trigger


Create Http based Logic app

In Logic app Designer add HTTP trigger followed by Create blob action (just keeping it simple :) )

logic app with split on


In Create blob action, I have specified the location where the blob is to be create with what name(PurchaseOrderNumber property in coming JSON) and the content of it(Whatever is received in trigger)

create blob  action

We need to set splitOn property on trigger, but no where it is visible -- Not able to understand why Microsoft has not provided.

No problem, we can still do it by going to Logic app code view, and under triggers, add splitOn property with value as path expression (same path is used as in For each above)


split on in logic app code view

Save it, and now you should be able to see in Designer view as well in trigger Settings


Split On in Trigger settings


Setting this property forces Logic App engine to create equivalent number of instances as that of number of repeating nodes, so if there are three repeating nodes in message posted to this logic app, then 3 different instance of this logic app will be instantiated.

Note: You can't use SplitOn with a synchronous response pattern , read Error related to this
-- The workflow with 'Response' action type should not have triggers with 'splitOn' property




Testing


Using Postman, sent a request(JSON PurchaseOrders) having three PurchaseOrder property in it to both the logic app



Logic App run history with Foreach control

Three emails were sent by this logic app

for each logic app history


Logic App run history with SplitOn property on trigger

Three blob were created in debatchedOrders container by three logic app instance

split on logic app history



Note: In both the logic app above message debatching happens, but in second approach the process/workflow also gets splitted (it scales out based on splitted messages by spinning new instances of itself). However in first logic app single instance does all the work.



Related Post 

No comments:

Post a Comment

If you have any suggestions or questions or want to share something then please drop a comment