Recipe Functions: Modular design for clean, readable & reusable automations
What are recipe functions?
Recipe functions are a recipe type introduced by Workato that allows users to build reusable recipe components. Recipe functions allow you to use modular design principles to break down complex systems into digestible modules, keeping your automations organized, readable and reusable.
Below, we will explore the importance of recipe functions and how you can leverage it to simplify your building process.
Why are recipe functions important for your automations?
To get the most value out of your automations, you need to build them to last. By applying modular design principles through recipe function, you can create automations that are organized, readable & reusable.
When you’re automating a critical business process, you want it not just to work today. You also want it to be:
- stable over time
- able to grow with your needs
- simple to maintain
It’s also important for other team members, who weren’t around while you were originally designing the automation, to be able to pick it up, understand it, and work with it.
Use recipe functions to improve readability
Developers who work with code follow a process called refactoring: taking code that already “works”, and rewriting it to be better organized, more efficient, and more readable. This step is essential for the long-term value of their work. The best low-code/no-code builders will do something similar with recipes and projects. Breaking down long recipes into smaller chunks with recipe functions can help you improve the readability and maintainability of your recipes.
How to tackle complex automation projects with recipe functions
When designing a recipe, or a more complex automation project, you focus first on building something that works. Then you go back and look at the design of your recipes, and the structure of your project.
Ask the questions:
- Is it easy to understand what this project does?
- Could parts of this project be reused?
- Could individual recipes be simpler?
- Does the project conform to internal standards and naming conventions?
Answering these questions is critical to being able to work together with your team to solve problems. An automation that only you can understand and maintain won’t be trusted by others, can’t be widely adopted, and won’t have long-term value.
Workato provides a suite of tools to help redesign your first drafts of recipes into productized projects that are easy to understand and maintain. For example, you can:
- Annotate assets at every level: the project itself, each recipe, and each individual trigger and action.
- Organize recipes and other assets into folders to give your project a coherent structure.
- Break up a large recipe into small reusable components with recipe functions.
This last point is the single most impactful thing you can do to improve your recipe design. With correct use of recipe functions, you can make your automations:
- Easy to read
- Simple to test
- Painless to maintain
- Consistent across the organization
Let’s look at these one by one.
How do recipe functions make your recipes more readable?
A great best practice when designing recipes is to try to imagine what it would look like to someone reading it for the first time. Ask yourself:
- Could a peer review it and give you meaningful feedback?
- Could a team member continue your work if you weren’t available?
To be able to collaborate effectively, your recipes need to be clear and readable.
Case study: creating an API endpoint
As an example, take a look at this recipe. It creates an API endpoint to capture raw lead information from a web form, validate and cleanse the data, and enrich it from third-party sources.
Yikes. This recipe “works”, in that it will successfully return cleansed and enriched lead data. But it runs to almost thirty steps, and it’s not very clear how each little step relates to the overall goal of the recipe.
If I asked you to take over ownership of this recipe, or fix an error, you’d probably struggle to figure out what was going on.
Using recipe functions
Now look at another version. This time, I’ve taken advantage of recipe functions to break up the recipe into manageable chunks. Each chunk does one easily understandable job:
Now, you can take a quick look at the recipe and understand, at a high level, what it does. If you need to change part of it, for example, the rules around email validation, you know exactly where to look.
Although both recipes take the exact same input and output, the second version is much more valuable, as anyone in your organization can pick it up, understand it, and use it.
How do recipe functions make automations maintainable?
As your needs change, your automations need to be able to evolve and grow over time.
Case study: lead validation API
Take the example of our lead validation API. Over time, you may want to improve some aspects of how you validate leads.
The original email validation process in the recipe above is pretty basic, just handling invalid address formats and checking for a few well-known free domains:
This is a good starting point, but a better long-term solution might be to use a dedicated email validation service, like Abstract API.
Think back to the long version of the lead validation recipe, without recipe functions. Even a simple change like this could be daunting to make. You would need to:
- Find and delete all the individual steps that relate to validating the email address
- Add in new steps calling the Abstract API service and interpreting the result
- Find and update any steps later in the recipe that depend on data from the steps you deleted.
- Repeat the process for any other recipe that needs to validate an email address.
Using recipe functions
Recipe functions make all of this a lot easier. When you create a recipe function, you define a simple input and output. In this case the input is just an email address. The output is a boolean value telling if the address is validated, plus the cleansed address itself.
All you need to do is rewrite your “Validate/Cleanse Email” function to use the third-party service.
Since the input and output don’t change, there’s no need to update the main recipe at all. There’s also no need to hunt down every recipe that needs email validation and update them individually. Update the function once, and the changes will take effect anywhere your function is invoked.
How do recipe functions promote consistency?
Another key benefit of creating reusable components with recipe functions is how easy it is to keep business requirements consistent across the organization.
Case study: email validation function
For example, let’s take another look at our email validation function. We’ve used the Abstract API service to determine whether the email address of a lead is valid.
However, Abstract API doesn’t just give us a “valid” or “not valid” response. Instead, we get a set of data designed to help us make the right decision for our particular requirements.
There’s information on:
- Whether the email is considered to be “disposable”
- If it’s from a free email service, as opposed to a work domain
- Whether deliverability for the email is confirmed
- An overall quality score
Now think about applying email validation across your RevOps stack. If each individual recipe builder has to call the Abstract API service, and decide for themselves what counts as a valid email, they’ll probably all come up with slightly different rules. You’ll end up in a situation where your marketing pipeline is rejecting leads that your sales team would consider valid, or vice versa.
Using recipe functions
Creating a recipe function doesn’t just save you time when building automations. It lets you define your business criteria once and apply them everywhere. In this case, you can use a recipe function to set one definition of a valid email address for your entire RevOps stack.
Now, individual recipe builders don’t need to worry about calling Abstract API and trying to decide on their own business rules. They can just invoke the recipe function, which returns a simple true/false response on whether an email is valid. All teams apply the same rules and get the same results.
How do recipe functions make recipes testable?
Here’s a simple rule of thumb: the more steps your recipe has, the harder it will be to test. Each new step in a recipe is an opportunity to introduce errors, and the more steps you have, the harder it is to track down the cause of problems.
Again, we can apply the experience of code developers to our low-code/no-code arena. Developers who work with code don’t just test a completed program. Instead, they create “unit tests” to make sure each discrete piece of code is working correctly, and to make sure that any changes don’t cause it to break.
Using recipe functions
Recipe functions help you to take a similarly structured approach to testing. They break up your recipes into manageable pieces, and each piece has a clear input and output. By testing each individual recipe function, you can easily find and fix errors, before they become a problem.
Turn projects into product
As low-code/no-code automation becomes more widespread throughout your organization, and as your projects become more ambitious, a focus on quality is essential to getting maximum value. Try to think of your automations not as short-term projects, but as product — built to last, to grow, and to evolve with you over time.
Organizing and standardizing your work with recipe functions makes it possible to work together with your team to create automation products that will solve tomorrow’s problems as easily as today’s.