Power Automate, The Direct Methodology
Tags: powerautomate, powerplatform, lowcode, rpa
Published: 2023-06-20 08:11:17

Everyone has their own particular style when making flows in Power Automate, and that is part of the beauty of being a developer. But development by its very nature is about sharing and learning from others (its why Stack Overflow is probably most visited developer site).

So after making far too many flows I've pulled together what I think of as the best approach to Power Automate (and many  other RPA tools), and its called the 'Direct' methodology.

The key focus is to:
- Use less actions
- Have less paths

Although when making a flow you have little control in the direction (top down) there are a few options how to get there. Different paths from start to finish are our model/schema. In the Direct Methodology there are 3 models:

- Christmas Tree
- Diamond
- Direct

The direct methodology is the drive to get all flows to the Direct model.

---
**Terminology**
- Container - action that contains other actions (Scope,Condition,Switch,ForAll,DoUntil)
- Logic - change of path (Condition,Switch)
- Nesting - actions within a container
- Nesting Levels - containers within containers
![nesting](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qyp8f6k610bur42fhmfr.png)

---

## Christmas Tree
This is the one you need to try and avoid, as the flow grows it expands horizontally, with multiple different logic paths, and worst of all many end points. 
The Christmas tree is defined by the high use of logics/loops/parallel branches with high nesting levels.

![christmas tree](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i6pegl2wljiebgzbmxj2.png)

**Example**
![christmas tree example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w9af9ct03x9npo5bsuk9.png)

## Diamond
Sometimes the complexity of a flow means that at a point we may need to grow horizontally and have nesting. But the path always converges to as close to a single path as possible.
A Diamond will still have nesting, but as minimal as possible, with different containers the main exception.

![diamond](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/64gmryg7xcd186a96n62.png)

**Example**
![diamond example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gpgnict41zqizcaidupo.png)

## Direct
The gold standard, one path from start to finish. There is only ever one level of nesting and branching is one sided (only one side is used).

Nesting happens in 3 ways, scopes, conditions/switch and loops (forAll & doUntil). Scopes are generally ignored in nesting controls, as they don't add complexity, but still should be kept to a minimum (personally max of 2 levels of nesting).

![direct](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dz49g3kaay8km652cyzy.png)

**Example**
![direct example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/40udoo54luibbskhuvpk.png)

---

## Getting from Christmas Tree to Direct
There are few golden rules and techniques that you can use to ensure your flows are as direct as possible.

The Golden Rules are
- Expressions before actions
- No duplication
- Break up large flows into child flows
- Avoid high nesting levels
- Terminate early
- Only one end path

To start lets go from **Christmas Tree to Diamond**, the Christmas schema is this

_The Christmas tree flow image can be converted to this schema_
```
trigger
->checks condition1
    -true 
        gets condition1 true items
        ->loops items
            checks condition2
            -true
                update item condition2 true
            -false
                get lookup items
                loops items ->
                    update item condition2 false with lookup
        set variable
        -true
            sends true email
    -false
        ->gets condition1 false items
            ->loops items
                checks condition2
                -true
                    update item condition2 true
                -false
                    update item condition2 false 
            set variable
            checks condition3
            -true
                sends true condition3 email
```

and the Diamond version is

_The Diamond flow image can be converted to this schema_
```
trigger
gets conditon1 items
->loops items
    ->checks condition2
        -true
            update item true
        -false
            ->checks condition2
                -true 
                    get lookup items
            update item expression condition2
        set variable
->checks condition3
    -true
    sends true condition3 email
```

The first thing we do is leverage the if() expression, why have 2 Get items with a condition when you can have just 1 Get Items.

![filter query](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l5dt5jj59zxhvd62rxws.png)

```
field_3 @{if(equals(triggerBody()['text'],'before'),'eq','gt')} '@{utcNow()}'
```

By doing this we are able to remove half of the flow actions.
The next step we want to do is push any duplicate actions out of the branching into the main branch. This again saves actions (if() expression can be used if any input variations), and it means we always have one end (great for when you want to debug).


Now to **Direct**

_The Direct flow image can be converted to this schema_
```
trigger
gets conditon1 items
->checks condition3
    -false
        Terminates flow
gets conditon1 and items
->loops items ->
    get lookup items
    update item expression condition2 & conditon1
sends true condition3 email
```
This expands on Diamond, with the addition of smart ordering. Just like making anything, the order you build it in will have big impact on how hard it is to make it.

The first thing we do is our terminate early. In the other 2 models we run the entire flow, even if there are no rows to do anything. Instead add a condition to check at the very begining.

Instead of a variable that is marked as true if one of the rows meets a condition, we query the list for the condition, if we get a body with length equals 0 then we terminate.

The next thing we do is take the expression approach to next level. As all paths are using update item, we can have one path. The extra get items action can be ran on every run, this may seem a little wasteful but it saves 2 Power Platform api calls (2 conditions) for 1 SharePoint api call. And again it makes everything so simple to follow.

And because the email send was a condition that we have already actioned (the terminate) every run will send the email.

---

A key example of the Direct methodology working is the escape condition. It terminates early but the key is to moving out of nesting and into a direct path.

_Dont do_
![nested condtion](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zuvskde92wdiim8d3a6p.png)

_Do this_
![non nested condtion](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qjytydbc56r6qcn8ekhg.png)

It may seem counterintuitive from the UI, but if you think about it in code it goes from
```
->condition
    -true
        action
        action
        action
    -false
```
to
```
->condition
    -false
        action
action
action
action
```
which is a lot cleaner.

---

This is an example, and real life is never so perfect. But the methodology is around getting as close to direct as possible. There will be times when diamond is the best solution, even times when christmas tree is (disposable quick proof of concept as example). But building in a way to be direct will improve stability, readability and have best optimization.