Process API – conditions

A big part of managing processes is being able to direct process steps using conditions. When performing conditions you can have a pass step and a fail step, but you don’t need to have both, you could also have either a pass step or a fail step depending on your requirements.

There are three type of conditions supported by the crs-process-api.

  1. Condition Checking: this involves evaluating a Boolean expression to determine its truth value. If the condition is met (true), a predefined ‘pass’ step is executed; if not (false), a ‘fail’ step is carried out if specified. This process is akin to a programmatic implementation of an if/else statement.
  2. Value Checking: this process entails examining a specific property path within an object. Depending on the value found, a corresponding task is performed. This method functions similarly to a switch/case statement, where different actions are taken based on the value’s case.
  3. Contingent Steps: this approach allows you to set various conditions and specify the actions to be taken if those conditions are met. Each condition is independently evaluated, and if it is true, the corresponding action is executed. The sequence of these conditions is irrelevant because every condition is individually assessed.

Condition Checking

{
    "id": "condigion_example",
    
    "main": {
        "steps": {
            "start": {
                "type": "condition",
                "args": {
                    "condition": "$context.person.age < 21"
                },
                "pass_step": {
                    "type": "console",
                    "action": "log",
                    "args": {
                        "messages": ["not an legal adult"]
                    }
                },
                "fail_step": {
                    "type": "console",
                    "action": "log",
                    "args": {
                        "messages": ["is an legal adult"]
                    }                    
                }
            }
        }
    }
}

In this example, we assess whether an individual is of legal age, set at 21 years. If the person is younger than 21, the message “not a legal adult” is displayed. Conversely, if they are 21 or older, the message changes to “is a legal adult”. This is done using a “condition” property within a step argument, which evaluates the person’s age. This example, drawn from JavaScript, leverages the language’s standard support for boolean expressions. Depending on the outcome of the condition, either the “pass_step” or “fail_step” is executed as the subsequent step.

The “pass_step” and “fail_step” can be either a string that references the next step in the process’s sequence of steps, or a distinct step object. The choice between using a string or an object depends on the specific needs: if a step is repeatedly referenced throughout the process, it should be included in the process’s sequence of steps. However, if a step is unique and used only once, it’s better to represent it as an object for clarity, as this approach aids in understanding the logic without needing to locate the step within the stack.

Value checking

{
    "id": "condigion_example",
    
    "main": {
        "steps": {
            "start": {
                "type": "switch",
                "args": {
                     "check": "$parameters.entityType",
                     "cases": {
                         "animal": "process_animal",
                         "alien": "process_alien"
                     },
                     "default": "process_default"
                }            
            },
            "process_animal": { ... step details ... },
            "process_alien": { ... step details ... },
            "process_default": { ... step details ... }
        }
    }
}

In this scenario, we receive a parameter named “entityType.” We employ a “switch” intent type to evaluate this parameter’s value. Our focus is on two specific values: “animal” and “alien.” Depending on whether the parameter value is “animal” or “alien,” we invoke one of two specialized steps. Additionally, there’s a “default” property that specifies a fallback step to execute if the parameter value doesn’t match any of the cases we’re specifically looking for. This default step is triggered only when none of the defined cases apply.

As a general guideline, it’s advisable to define a default step as a safety net for scenarios not covered by the specified cases. While this isn’t a mandatory practice, it helps ensure that unforeseen values are handled appropriately. However, there can be situations where you deliberately omit the default step. For instance, if there are ten potential unique values but you only want to address three, the process should terminate if the value doesn’t match these three. This deliberate omission of the default step in such scenarios serves to halt the process, acting as an exception to the usual rule of including a default step.

Similar to conditional checks, the step can be specified either as a string or as an object, each defining the subsequent step in the process.

Contingent Steps

{
    "id": "contingent_example",
    
    "main": {
        "steps": {
            "start": {
                "type": "contingent",
                "args": {
                    "contingents": {
                        "$data.value == 10": {
                            "type": "console",
                            "action": "log",
                            "args": {
                                "message": "value is 10"
                            }
                        },
                        "$data.value == 20": {
                            "type": "console",
                            "action": "log",
                            "args": {
                                "message": "value is 20"
                            }
                        },
                        "$data.value == 30": {
                            "type": "console",
                            "action": "log",
                            "args": {
                                "message": "value is 30"
                            }
                        }
                    }
                }
            }
        }
    }
}

The steps defined can either be the step name to execute in the same process or the step object definition.