Author:
Fluent Commerce
Changed on:
30 June 2024
The `run`
Since Rules are the smallest building block for logic, it is important to remember that this method should be implemented to perform 1 simple task. Rarely should your Rule code ever be more than a few lines of code.
Rules are meant to be composable, and this means they should be self-contained, and not depend on any other Rule.
The
`run`
`Context`
Rules are singletons, meaning the same single instance of the Rule is processing multiple threads. To this point, make sure you do not declare any runtime-specific values in the Rule Class properties, as these will not be threadsafe.
To implement the Rule, the following steps are usually followed within the
`run`
`context.action()`
You may not need all of these steps within your Rule. Some rules produce an action without a condition. Some rules do not need to query additional data. Make sure your Rule is as lean as possible, and simple to read.
A good practice for writing Rules where the resulting action is conditional, or where validations fail, is to exit early. This means avoiding difficult-to-read nested if statements. The logic should be as simple as possible. If there are too many conditions or evaluations in the Rule, it is likely too big and complex, and needs to be broken down into smaller building blocks for the composition of the logic in the Workflow.
Remember, your Rule should be reusable, and should be possible to position it one or more times in a Ruleset and Workflow.
To learn more about how to write well-crafted Rules, see Rule Coding Best Practices.
This stage typically involves validating all the required inputs to the Rule are both present, and valid. For example, if you have declared a number of Parameters or Event Attributes for use within the Rule logic, you should validate these first.
The Rubix Plugin SDK provides a useful Util class to facilitate validation:
`RuleUtils`
For example, this snippet validates that the Order Id parameter exists:
1// imports & Rule Info annotation...
2@ParamInteger(name = "MyInt", description = "An Integer value for the Rule")
3public class MyCustomRule implements Rule {
4
5 // local fields...
6
7 public void run(C context) {
8
9 // Validation:
10 RuleUtils.validateRuleProps(context, "MyInt");
11
12 // continuing logic...
13
14 }
15}
Language: java
Name: Example
Description:
[Warning: empty required content area]If any required validation fails, your Rule should exit immediately. To do this, you have 2 options:
`return`
The choice of option is dependant on the behaviour you are expecting when this Rule's validation has failed.
For some Rules, this would indicate a critical error, which for others, it might simply indicate not to continue the logic and behaviour of the existing rule, but simply continue executing the following rules in the Ruleset.
Only you can determine the appropriate behaviour for your rule. The SDK
`RuleUtils`
Once you've completed the Validation phase, you may wish to retrieve any additional data you may need to execute your Rule logic.
The
`Context`
`context.getEntity()`
It only contains the primary information (the common generic fields) of an Orchestrateable Entity:
Should you require more data from the specific Entity itself, you will need to perform a query using the GraphQL API Client available on the
`Context`
For example, if you are writing a rule that needs to operate on a field or attribute of the Event Entity, you can retrieve this via a GraphQL query.
1// imports & Rule Info annotation...
2@ParamInteger(name = "MyInt", description = "An Integer value for the Rule")
3public class MyCustomRule implements Rule {
4
5 // local fields...
6
7 public void run(C context) {
8
9 // ...preceding logic
10
11 // Retrieve Data:
12 String orderId = context.getEntity().getId();
13
14 GetOrderByIdQuery query = GetOrderByIdQuery.builder().id(orderId).build();
15 GetOrderByIdQuery.Data data = (GetOrderByIdQuery.Data) context.api().query(query);
16
17 RuleUtils.validateQueryResult(context, data, this.getClass());
18
19 // continuing logic...
20
21 }
22}
Language: java
Name: Example
Description:
[Warning: empty required content area]To learn more, see Working with GraphQL.
The next stage within the
`run`
Let's say that for example, you only wished to continue the action of this rule if the
`totalPrice`
`threshold`
1// imports & annotations...
2public class MyCustomRule implements Rule {
3
4 // local fields...
5
6 public void run(C context) {
7
8 // preceding logic...
9
10 // Simple Logic:
11 if (data.orderById().totalPrice() <= threshold) {
12 return;
13 }
14
15 // continuing logic...
16
17 }
18}
Language: java
Name: Example
Description:
[Warning: empty required content area]Typically, a Rule will produce an output action. See Rule Actions here.
Some typical examples of output actions include:
In each of these cases, the data to be included in the action will need to be prepared.
1// imports & annotations...
2public class MyCustomRule implements Rule {
3
4 public void run(C context) {
5
6 // preceding logic...
7
8 // Prepare for Action:
9 AddAttributeToOrderMutation addAttributeToOrderMutation = AddAttributeToOrderMutation.builder()
10 .orderId(orderId)
11 .attributeName(IS_HIGH_VALUE_ORDER_ATTRIBUTE_NAME)
12 .attributeType(Attribute.Type.BOOLEAN.getValueClass().getSimpleName().toUpperCase())
13 .attributeValue(Boolean.TRUE)
14 .build();
15
16 // continuing logic...
17
18 }
19}
Language: java
Name: Example
Description:
[Warning: empty required content area]To learn more, see Working with GraphQL.
The final stage of the
`run`
1// imports & annotations...
2public class MyCustomRule implements Rule {
3
4 // local fields...
5
6 public void run(C context) {
7
8 // preceding logic...
9
10 // Produce Action:
11 context.action().mutation(addAttributeToOrderMutation);
12
13 }
14}
Language: java
Name: Example
Description:
[Warning: empty required content area]Copyright © 2024 Fluent Retail Pty Ltd (trading as Fluent Commerce). All rights reserved. No materials on this docs.fluentcommerce.com site may be used in any way and/or for any purpose without prior written authorisation from Fluent Commerce. Current customers and partners shall use these materials strictly in accordance with the terms and conditions of their written agreements with Fluent Commerce or its affiliates.