Best practice for common rule override

Certified Associate Developer

hi,

My team wanted to build a common library/application i.e. Global_CaseManagement where the application will be exported to 2 instances for 2 regions to share (similar to a common library), i.e. UK_Bank  and US_Bank.
Let's name the rule as rule!Global_GetNextCase which used within a node by a common global process model namely ACTION - Get Next Case

Given the rule Global_GetNextCase will have different logic for UK and US, what would be the recommended way to do the common rule override?

The dependency graph as below :
1. Global (application) -> ACTION - Get Next Case -> rule!Global_GetNextCase -> rule!Global_GetNextCase_UK
2. Global (application) -> ACTION - Get Next Case -> rule!Global_GetNextCase -> rule!Global_GetNextCase_US

This way will create a problem where both UK and US rules will be imported into the instances respectively causing unwanted dependency issue, cause UK only needs Global_GetNextCase_UK while US only needs Global_GetNextCase_US


Another method by using local!result: getrulereferencebyname("rule!Global_GetNextCase_" & cons!region) where this way will resolve the unwanted dependency issue, but it will be dynamically calling the expression rule, we are thinking this might not be the best practice since the dependency cannot be traced.

Any suggestion on the best practice?

  Discussion posts and replies are publicly visible

Parents
  • Certified Lead Developer

    Possibly the best solution I've seen where you want to avoid porting cross-application dependencies around to relatively-unrelated instances is to set up API calls for each specific environment.  So basically instead of calling a rule by name (not really a good practice even at the best of times, and super vulnerable to things like renaming and version issues), you'd refernce an API endpoint (stored as text in a constant or something) and call the relevant Web API which then passes back the info you want.

  • Certified Associate Developer
    in reply to Mike Schmitt

    hi mike, thanks for helping. Web API could be an alternative, what if we have hundreds of environmental overrule required for the expression rules or interfaces in the Global application for 2 countries, is having hundreds of Web API a doable plan as suggested? 

    Allow me to let me rephrase my question, both UK/US instances will be using the same Global application, just that within the node (expression rule) of the shared Global process model/parent expression rule, each country might have different logic in the implementation, hence overrule is required. The goal is to share the common utility/expression rule/interface as much as possible while allowing overrule for some of the precedence/child expression rules.

  • Certified Lead Developer
    in reply to weiliml1795

    Appian supports passing references to expressions. So when calling such an expression, you could implement generic stuff directly in that expression. For local stuff, you could call an expression that returns a rule reference based on some conditions. Then evaluate that reference passing data based on a fixed interface contract.

    I describe this in my blog post: https://appian.rocks/2022/09/19/building-customisable-components/

    For expressions, this should work, for processes, you would need a comparable concept. The "Start Process" node can start any process based on the model id. A decision table can be used to implement a dispatching logic.

  • Certified Lead Developer
    in reply to weiliml1795
    what if we have hundreds of environmental overrule required for the expression rules or interfaces in the Global application for 2 countries, is having hundreds of Web API a doable plan as suggested? 

    That sounds like a pretty big upkeep burden, but AFAIK if you figure out the simple way to do this with WebAPIs, it's no more of a burden than trying to do it with rule references (and also perhaps with less technical risks, though i'm not sure). 

    Honestly though if it were me I'd be looking into a way to more generally avoid such a large burden of regional exceptions like this, as much as possible, before implementing anything. 

    Beyond that, it'll really be down to you and your dev team to experiment with a micro-scale version of the 'system' you want to use for this, and figure out what method will scale up to your demands the most easily.

  • Certified Associate Developer
    in reply to Stefan Helzle

    hi Stefan, have checked the document you shared.

    Cmiiw, to use the method, we will need a wrapper expression in order to pass in the custom rule reference. e.g.
    rule!Global_GetNextCase_UK -> rule!Global_GetNextCase(contentExpression:rule!_my_rule) -> rule!_my_rule

    This method is good, but it gets tricker when the depth of dependency is too high. e.g.
    PM-Global - Get Next Case -> rule!Global_GetNextCase(contentExpression:rule!_my_rule) ... -> rule!_my_rule(UK rule)
    To pass the reference, the rule has to be rule input of many rules in between.

    Is there anyway we can achieve this by sharing the same base process model? e.g.
    1. PM - Get Next Case -> rule!Global_GetNextCase -> rule!_my_rule(UK rule)
    2. PM - Get Next Case -> rule!Global_GetNextCase -> rule!_your_rule(US rule)

    We have quite a number of nodes in process models to share the same base logic block while differs on partial logic for regional requirement.

  • Certified Associate Developer
    in reply to Mike Schmitt

    hi Mike, the requirement is to share the same base expression (without having to code twice for 2 instances), while allowing partial expression to be overridable by the region, similar to Template method pattern.

  • Certified Lead Developer
    in reply to weiliml1795

    Yep, that's the compromise with low-code. Trying to develop something like a "base product" becomes extremely tricky. I suggest to contact Appian to discuss this with their architects.

Reply Children
No Data