Monday, May 20, 2024

Power Automate - A Collection of Best Practices

 This is a personal collection of best practices for Power Automate. This individual practices are only mentioned, not explained. However, feel free to comment and ask me to elaborate on a specific point! This list ist likely to grow in the future...

Code / Flow Quality and Efficiency

  • Always give your actions good names that describe that they do without getting to long. If you need to provide more info, do it with the "Add note" feature. 
  • Good names for conditions: Frame them as a question (without the question mark, since it's not allowed). Some examples: "does array have a single result", "any links to add", "is tomorrow the first day of the month". 
  • Good names for actions: Keep their default name, but add some details thereafter. E.g. "Filter Array - matching email", "Create an email - notification to operator", ...
  • Use scopes. Two reasons! 1) They help to make your flow more lean by collapsing actions that solve a specific problem within the flow into a single object. 2) If anything fails inside a scope, then the flow doesn't immediately crash. Instead the surrounding scope will fail. You can then use a "configure run after" to handle the failing scope. This technique is part of the "try - catch - finally" approach which makes your flows MUCH more robust!
  • Limit your use of "Apply to each". It is fairly slow! Use Actions like "Filter Array", "Select", or join() and union() functions to accomplish your goals. The difference in speed is staggering! 
  • Variables vs compose statement: Know when to use which! 
    • Variables: 
      • have to be initialized (has to be outside of a loop).
      • data type has to be declared when initializing it.
      • can be set as many times as you like 
      • loops with access to variables inside should have concurreny = 1
      • can't access themselves (self-referential); but specific actions exist to increment and append to their values
    • Compose:
      • Can only be set once - inside the Compose action
      • very flexible, can even be created inside of loops
      • will assume the data type of its input (e.g. from dynamic content or expression)
      • Very handy when debugging your Code, especially before Conditions, since conditions don't show their values (right or left side) during runtime.

Robustness and Security

  • Use service accounts for business-critical flows. This may also reduce licensing costs.

  • "Apply to each" loops with variables inside should always have concurrency = 1. Otherwise parallel executions of the loops will lead to unpredictable outcomes
  • If you have a whole tree of child flows, carefully draft an error handling procedure: What errors are handled inside the child flow, which ones are passed upwards and which ones are simply ignored. Keep a list of this.
  • Instead of hard-coding things that you expect to change in your flows, consider building a Configurations table with key-value pairs: e.g. operator_email, website_link, version_number... Then build a child flow that returns the value of a configuration given a specific configuration key. Include the Configuration table in your documentation to the operating users.
  • Never use actions marked with "(Preview)" for anything remotely business-critical! Previewed actions are very likely to become obsolete, as soon as the non-preview version is released. This will break your flows! It's of course fine to use them for experimenting with upcoming features though.

Data Sources

  • Avoid excel lists as data sources
  • If you use a Sharepoint list as data source, do it only once per flow! I see often that people use "get items" inside an "Apply to each". Instead use Filter Array to load the row(s) from the whole datasource. Filter Arrays are extremely useful and fast.

Dataverse

  • Refer to a Choice column always by its value, not its label. Labels may change over time, but values tend to stay the same, since they are usually not exposed to the user. This is also faster btw. But as a negative consequence though, your Power Automate code will be less easy to read...

  • Your Dataverse tables always should have two IDs, an internal ID (containing the GUID of the record, already present in table, column name == table name) and a human-readable ID (can be configured as auto-generate, e.g. "rec-000024"). Let the users refer to the record by their human-readable ID. But then inside your flow first search for the that record and then specifically load it with "Get Row by ID" (providing it the resulting internal ID of your search). This has the advantage that you won't get back an array of rows, but only a single record. A good way to avoid the "Apply to each" chaos when dealing with arrays of rows...

Copilot

  • (As of June 2024) Forget about Copilot inside of Power Automate! Use ChatGPT 4o instead. It is about 1000x more useful for this. But be aware that ChatGPT may gaslight you with inexistent functions and actions :D.

No comments:

Post a Comment

Insanely fast synchronization from a Dataverse table to a SharePoint List

Don’t be fooled: this challenge is deceptively hard — at least if you want to make it fast, efficient, and robust .  Feature specs Your sour...