When I reach out and ask the community what they would like me to share, I primarily get asked for Best Practices. For a time I have rejected the idea of sharing those in too much detail as I consider Best Practices to be part of the value proposition of a consultant practice. It's taken years to forge and sharpen those practices and they therefore have value. We continue to challenge those and update as new scenarios, tools, and skills evolve over time. But I continued to think about this and have had a change of opinion.
Our experiences with projects and tools that allow us to design solutions around the best practices are our value, not the practices themselves. Akin to other disciplines like Medicine, and without a formal peer-reviewed journal, it makes sense for us as Experts and MVP's to share our ideas so they can be challenged so we all get better at what we do. Therefore, I want to open up and share so we can all figure out the optimal ways to make our projects the most successful they can be. The community and practitioners still need experienced resources that know how to wield these best practices and we can find our value in that manner. So without further adieu, I'll start with some best practices we apply to designing and building Microflows.
Use of Color
After some great community feedback, Mendix created a feature so that developers could change the color of the actions in a microflow. The concept was simply that we could use that color in any manner we desired to help us organize the steps in a Microflow. What that quickly became for us was a need to establish standards so that members of my staff could always recognize certain actions and steps at a glance of a microflow instead of reading step by step. Here is how we use the colors:
Purple - Variables that are declared (not return variables) as well as any step that changes the variable.
Yellow - SubMicroflows. This one is very important to design.
Grey - Messages and Log Entries
Green - Commit
These four would otherwise default to the standard blue like every other action, but they are crucial in a flow to see at a glance. Also we don't want to overwhelm and create rainbows for every action type, just draw the eye to the key steps in the flow. My team occasionally uses Red to distinguish a message that is specifically an Error, but we don't standardize on that as I don't want to over complicate. Things like Java Actions and Error Handling already has symbols on the action that make them standout. Here's an extreme example of the colors in use and how without reading anything I can tell if the flow is handled well:
Keep it small and use Sub Microflows
I could get into a long lecture about Object-Oriented design for this but of course won't. Code should be written in small, bite-sized transactions. When I've reviewed code with early developers, the most common issue I see is they try to create these gigantic Microflows that complete a transaction from end to end. The code will work, but it is a maintenance and legacy nightmare. You want to break each piece of the transaction up into smaller transactions so that a) if you want to make changes, you don't have to retest dozens of related actions and b) if you ever decided to change that part of the transaction, you don't have to refactor the entire overarching transaction, just the piece. This is the kind of thinking that has pushed Microservice architecture to the forefront.
As an example, a developer needs to a create transaction when a user clicks "Save". That transactions requires:
Changing the Status
Committing the page objects
Sending an email to the next person in the process
Sync the data with a 3rd party system
Close the page
The Best Practice approach would be to build AT LEAST 6 Microflows: One for each of the sub-transactions and one overarching microflow that calls each of those as a submicroflow in the order needed. Within each of those steps you will likely have multiple submicroflows to build as well. For example, the "Sync" step will likely have a sub to get the API Config data, a sub to stage the data to map to the call, a sub to call the api, a sub to handle errors…you get the idea. Using this hierarchy approach, you now have individual code pieces that can be reused in your app as needed. If you need to call that Sync API for another process, you don't have to start from scratch, just call the same API Config, API Call, Error Handler, etc, and write a new sub routine to stage the data according to the mapping.
I realize we could take this further and analyze this scenario to setup some of these transaction steps as Event handlers but that is for a different topic.
Always handle the Retrieve of 'EMPTY'
This bites developers all the time, myself included. Even after doing this thousands of times, I might forget to immediately check a retrieve for empty using an exclusive split, and inevitably, not matter how improbable the scenario is, a UAT tester or production user will cause an empty retrieve. Bank on it. So as a best practice, whenever you have a 'Retrieve Action', IMMEDIATELY follow it with an Exclusive Split and check for Empty and handle it (log it, message it, email it…whatever, but handle it). It takes less than a minute to do this and will save you future pain.
Always Setup an Error Handler on Java Actions
Especially Integrations! The most well thought out integration can fail due to network traffic issues. If you timeout, lose packets, expire your certificate…you will have an error that needs to be handled. If I see a Java Action in a microflow, I must see an Error Handling icon and flow setup, preferably with logging on the stack trace and any other relevant data.
Name your variables with a 'vName'
Put a lower case 'v' in front of your variable names so they are easy to locate when writing logic. Whether Xpath or formulas, you can hit CTRL+C, $v and immediately see your variables.
This one is a bit of a no-brainer but gets overlooked often. The visual code method should serve adequately to document the code, but sometimes we bury a lot of logic inside of a step. For example, an Exclusive Split might have complex logic and you can't summarize that in one or two words. Attach an Annotation to the split and write your name and date (so future devs know who had the knowledge of that action) and describe what is happening. This is also use on change objects where you are changing a lot of attributes and the code might be buried on each attribute. Summarize what is happening so a business user can understand the process map at a glance.
Setup Logic to flow right and down
This might be different in Asia, but in the Western world we read top to bottom, left to right. Your code flow, therefore, should flow similarly. If you have an Error Handler or Exclusive Split, make sure the logic keeps the transaction flowing to the right and go down for secondary and beyond split paths. This one is a bit controversial because I've seen people fork their code with splits that go vertically up, but as a best practice, I recommend you steer away from that so that Microflow is always centered with the Start (green circle) being the highest point and furthest left of a flow.
This is a taste of the some of the best practices we employ when developing micoflows. There are many more I'm likely leaving off the list but I'll make it my focus for a while to capture best practices across many different project areas. If you disagree with anything I write, please comment and let's work on building a reference guide for current and future Rapid App Developers who use Mendix!