[et_pb_section fb_built="1" _builder_version="4.1"][et_pb_row _builder_version="4.1" hover_enabled="0"][et_pb_column type="4_4" _builder_version="4.1"][et_pb_text _builder_version="4.1"]

Putting it all Together

We continue our journey through Microsoft Flow. After covering some of the Flow calling other Flows and recursion concepts in the previous posts, we are going to go through the overall idea of what we are building and to test out the overall performance.
[/et_pb_text][/et_pb_column][/et_pb_row][et_pb_row _builder_version="4.1"][et_pb_column type="4_4" _builder_version="4.1"][et_pb_text _builder_version="4.1"]

We will use Flow to generate some JSON for the organizational hierarchy, which can then be used in various org charts around the business. There is a specific D3.js library, which will be used to display it all, but for now we going to cover the overall structure to generate it all properly.

For transparency, using Flow is probably not the best way to do this, just given the number of workarounds to achieve what should be basic programming techniques. This org chart approach is pushing the limits of what we can do with Flow just to see how far we can get with its functionality. Its huge advantage is that it is available to anyone using Microsoft 365, so even though it may not be an elegant solution at times, it is hugely powerful by putting this kind of automation in the hands of every user.

Microsoft Flow Performance

Each HTTP call has a performance hit, which in a recursive traversal will add up. This is not the most efficient way to traverse a very large organization hierarchy in Microsoft 365. So, a department of about 30 individuals will take roughly 50 seconds to traverse and a larger group of 60 individuals can approach the 120 seconds maximum. These timings can fluctuate, most likely due to the load and capacity of the underlying compute that Microsoft puts at the disposal of Flow.


There are two Flows, the “Get Manager Org JSON” is currently the main entry point, which pulls the manager details, and then calls the “Get Direct Reports JSON” Flow to get the reports, and that has the logic to call itself multiple times to get all the levels of reports below.

[/et_pb_text][et_pb_image src="https://3bb4f13skpx244ooia2hci0q-wpengine.netdna-ssl.com/wp-content/uploads/2020/06/Two-flows.png" show_in_lightbox="on" _builder_version="4.1"][/et_pb_image][et_pb_text _builder_version="4.1"]

We could look at some form of caching. If the Flow is traversing an organizational hierarchy and along the way encounters a manager has already been mapped out, we could just reuse that. So, if we start with lower level managers, save their results to say a SharePoint library, then assemble that existing JSON into any calls above that manager we can avoid doing the traversal from scratch.

Saving to SharePoint

We start by adding a step (1) to our “Get Manager Org JSON” Flow, which will save the output of the JSON to a SharePoint site. We can use the manager name as the filename to be able to reference that same JSON later.

[/et_pb_text][et_pb_image src="https://3bb4f13skpx244ooia2hci0q-wpengine.netdna-ssl.com/wp-content/uploads/2020/06/Save-to-SharePoint.png" show_in_lightbox="on" _builder_version="4.1"][/et_pb_image][et_pb_text _builder_version="4.1"]

Then in the “Get Direct Reports JSON” Flow we add the corresponding conditional within the loop that if the direct report is a manager and that manager already has the JSON saved to the SharePoint site (2), simply read that JSON rather than traverse. Otherwise if no saved JSON, then traverse.

[/et_pb_text][et_pb_image src="https://3bb4f13skpx244ooia2hci0q-wpengine.netdna-ssl.com/wp-content/uploads/2020/06/Read-from-SharePoint.png" show_in_lightbox="on" _builder_version="4.1"][/et_pb_image][et_pb_text _builder_version="4.1"]

The Result

The larger group which took ~120 seconds to traverse, is now completed in under 10 seconds when assembling 5 pre-populated org charts for the direct reports. This is saves time tremendously with a simple tweak to save results to a SharePoint site. More importantly, this shows how several of the Microsoft 365 features can be joined up to solve an interesting programming challenge.



Date(s) - 01/01/1970
12:00 AM - 12:00 AM


600 5th ave. NY, NY
[et_pb_section fb_built="1" _builder_version="4.1"][et_pb_row _builder_version="4.1" hover_enabled="0"][et_pb_column type="4_4" _builder_version="4.1"][et_pb_text _builder_version="4.1"]

Need Recursion in Flow?

In a previous blog post Flows Calling Flows, we covered how we can have one Flow call another Flow using the scenario to return some information on the direct reports of a user. We now want to take it further and solve the challenge of returning the direct reports for a user, then all the direct reports of those direct reports, and again and again through however many levels of hierarchy there is in an organisation.

[/et_pb_text][/et_pb_column][/et_pb_row][et_pb_row _builder_version="4.1"][et_pb_column type="4_4" _builder_version="4.1"][et_pb_text _builder_version="4.1"]

This is a common technique in programming and is called a recursive function. We can recreate a similar effect in Microsoft Flow, because as we learnt a Flow can call another Flow via an HTTP request and receive, so therefore we can do it recursively with a Flow calling itself.

Microsoft Flow Limitations

Obviously, recursion is not a native feature of Microsoft Flow and we need to be aware of some of the limitations when using HTTP requests to mimic recursion. All Microsoft Flow limitations can be reviewed here: https://docs.microsoft.com/en-us/power-automate/limits-and-config.

One important limit is the request timeout for synchronous calls, which means that an HTTP request which remains connected to receive data may not last more than 120 seconds. Using our scenario for recursion through the organisational hierarchy, from the first HTTP call for the manager through to the completion of all the recursive calls of all the direct reports, the total time cannot exceed 120 seconds. This will be important to consider in larger hierarchies.

There is a way to get around this limitation with the asynchronous calls, but that requires using webhooks to listen separately for the received data as and when it is received. The other important limitations are the concurrency/parallelism and rate limits, which we will cover in a separate post about optimisations.

Child Flow Calling Itself

In the previous example of a parent Flow calling a child Flow which the iterates through a manager’s direct reports, the user details of each found direct report are appended to a string variable. A new step (1) is added to the Flow, before the variable appending, which will result in the Flow calling itself.

[/et_pb_text][et_pb_image src="https://3bb4f13skpx244ooia2hci0q-wpengine.netdna-ssl.com/wp-content/uploads/2020/06/Adding-an-HTTP-call.png" show_in_lightbox="on" _builder_version="4.1" transform_styles__hover_enabled="on|hover" transform_scale__hover_enabled="on|hover" transform_translate__hover_enabled="on|desktop" transform_rotate__hover_enabled="on|desktop" transform_skew__hover_enabled="on|desktop" transform_origin__hover_enabled="on|desktop"][/et_pb_image][et_pb_text _builder_version="4.1"]

The same child Flow URI is used in the HTTP request (1) and the current loop iteration direct report’s UPN is passed as the manager attribute. The returned data is also appended to the JSON variable.

[/et_pb_text][et_pb_image src="https://3bb4f13skpx244ooia2hci0q-wpengine.netdna-ssl.com/wp-content/uploads/2020/06/Adding-an-HTTP-call-details.png" show_in_lightbox="on" _builder_version="4.1"][/et_pb_image][et_pb_text _builder_version="4.1"]

This is what allows this Flow to traverse an organisational hierarchy. As it digs deeper into a branch, once it reaches the end point when a user has no direct reports, then the loop will not trigger, no further recursive calls to the Flow will happen and a blank string will be returned.

Organisational Hierarchy Using Flow

The end result below can be seen in the resulting JSON from the call to parent Flow. The first manager (1) has a direct report (2), who in turn also has a direct report (3) represented in the JSON.

[/et_pb_text][et_pb_image src="https://3bb4f13skpx244ooia2hci0q-wpengine.netdna-ssl.com/wp-content/uploads/2020/06/Final-JSON-results.png" show_in_lightbox="on" _builder_version="4.1"][/et_pb_image][/et_pb_column][/et_pb_row][/et_pb_section]


Date(s) - 01/01/1970
12:00 AM - 12:00 AM


600 5th ave. NY, NY
[et_pb_section fb_built="1" _builder_version="4.1"][et_pb_row _builder_version="4.1"][et_pb_column type="4_4" _builder_version="4.1"][et_pb_text _builder_version="4.1"]

Microsoft Flow, also known as Power Automate, allows you to create and automate tasks via numerous applications and services swiftly and easily. In MS Flow, these automated workflows are referred to as 'Flows' and it intuitively integrates a variety of Microsoft services and apps (Dynamics 365, Office 365, Power BI etc.).

Flow Building Blocks

When building Flows one of the approaches to simplify their structure, help troubleshooting and create re-usable modules is to make the Flows call other Flows. Natively, Microsoft Flows does not have a way for a Flow to call another Flow. However, Flows can be triggered on an HTTP request and they can also make HTTP calls, hence they can call each other by combining an HTTP request receive trigger and an HTTP request action.

Child Flow

We are building some Flows to help around our organizational structure. Create a new Flow, search for HTTP triggers to add, and there will be a one called “When an HTTP request is received”:

[/et_pb_text][et_pb_image src="https://3bb4f13skpx244ooia2hci0q-wpengine.netdna-ssl.com/wp-content/uploads/2020/06/HTTP-Triggers.png" show_in_lightbox="on" _builder_version="4.1"][/et_pb_image][et_pb_text _builder_version="4.1"]We can start building a new child Flow, which will do one thing. In this case, what we would like to do is for any user in our organization to return their direct reports if they have any. We create the HTTP trigger (1), which has the option of being a POST or a GET method (2). In this case, we are using the GET method as we want this to be as universally available outside of Flow, even for systems which are not able to submit a POST call. Once this call is received this child Flow carries on with some other actions (3). [/et_pb_text][et_pb_image src="https://3bb4f13skpx244ooia2hci0q-wpengine.netdna-ssl.com/wp-content/uploads/2020/06/Child-Flow-to-Call.png" show_in_lightbox="on" _builder_version="4.1"][/et_pb_image][et_pb_text _builder_version="4.1"]The first variable we initialize called “Manager” will be to store the manager username we receive from the GET attribute “manager” (1). The second variable “DirectReportsJSON” (2) we need to store the results as a JSON string. The Office 365 action “Get direct reports (V2)” is used in the “GetDirectReports” step (3) to query for the manager user in Office 365, fetch the direct reports, and pass them onto the loop (4). In the loop we iterate through the direct reports and compose the “DirectReportsJSON” contents. Finally, the “ReturnDirectReportsJSON” step (5) takes the variable “DirectReportsJSON” contents (6) and returns out of the Flow with a success code 200. [/et_pb_text][et_pb_image src="https://3bb4f13skpx244ooia2hci0q-wpengine.netdna-ssl.com/wp-content/uploads/2020/06/HTTP-Return.png" show_in_lightbox="on" _builder_version="4.1"][/et_pb_image][et_pb_text _builder_version="4.1"]

Parent Flow

In another Flow which will be the parent, we want to invoke this child Flow. This parent Flow we will use for fetching all user details from Office 365, including their direct reports information which will be provided by the other Flow we just created.
  • Add an HTTP request action which will make a GET method call to our other Flow (1).
  • Use the URI provided by the trigger in the other Flow and move the attributes to the queries section (2), include also the “manager” attribute to search for.
[/et_pb_text][et_pb_image src="https://3bb4f13skpx244ooia2hci0q-wpengine.netdna-ssl.com/wp-content/uploads/2020/06/Parent-Flow.png" show_in_lightbox="on" _builder_version="4.1"][/et_pb_image][et_pb_text _builder_version="4.1"]

Calling Parent Flow

If we now test by calling the URI of the parent Flow, and passing it a manager attribute we can see the combined results in a single JSON:
  • The manager section provided by the parent Flow (1)
  • The direct reports appended to the manager from the child Flow (2)
[/et_pb_text][et_pb_image src="https://3bb4f13skpx244ooia2hci0q-wpengine.netdna-ssl.com/wp-content/uploads/2020/06/JSON-Final-Result.png" show_in_lightbox="on" _builder_version="4.1"][/et_pb_image][/et_pb_column][/et_pb_row][et_pb_row _builder_version="4.1" hover_enabled="0"][et_pb_column type="4_4" _builder_version="4.1"][et_pb_text _builder_version="4.1"]

We now have the option of calling for a combined action to return manager details and the direct reports, or reuse the child Flow in other operations when we just want the direct reports.

Stay tuned for more MS Flow content. People are always looking for the most intuitive way to increase automation for their workflows. Mastering MS Flow helps you achieve this, in addition to improving development efficiency.



Date(s) - 01/01/1970
12:00 AM - 12:00 AM


600 5th ave. NY, NY