A maintainable service can be changed with low risk. In the Designer, maintainability depends on the process model and data structures being easy to follow, custom code staying disciplined and small, and the people who didn't build the service being able to safely support or extend it later.
This page covers practical best practices for using Action Script or JavaScript.
Keep Scripts and Custom Logic Disciplined
Designer supports technical implementation concepts such as Action Script Language, JavaScript specifics, libraries, and pro-code development. These capabilities are powerful, but they should be used carefully.
-
Always model business decisions graphically using gateways — never hide a business flow decision inside Action Script.
-
Use script logic only when modeling or standard configuration is not the clearer option.
-
Keep script blocks small, readable, and purpose-specific.
-
Split a large script into separate sub-logics (e.g. order header vs. order items) rather than one long block.
-
Avoid spreading similar script fragments across many services. Consider creating a library instead.
-
Document non-obvious script behavior, assumptions, and dependency expectations, e.g. in comments.
Be careful with custom code: Robustness decreases when critical business behavior is hidden in scattered, undocumented scripts that only one developer understands.
Use custom code when standard modeling, mappings, or built-in capabilities are not the clearest or most maintainable solution. Keep it focused and reusable.
Examples
Prefer
Operation: Order.validate() : Boolean
// An order is only valid when it has at least one line item and every item carries a strictly positive price and quantity.
set result = self.items.exists()
and self.items.count() > 0
and (select each from self.items
where element.price > 0.0 and element.quantity > 0).count()
= self.items.count();
Operation: Order.calculateSubtotal() : Float
// Sums (price * quantity) across every line item.
local lineTotals = apply element.price * element.quantity
to self.items;
set result = reduce lineTotals using element + nextElement
if single use element;
Order.calculateDiscount(subtotal : Float, premiumThreshold : Float, standardThreshold : Float) : Float
// Premium customers get 10% off orders over 500; everyone else gets 5% off orders over 1000.
set result = if self.customerType = "PREMIUM"
then (if subtotal > premiumThreshold
then subtotal * 0.1 else 0.0)
else (if subtotal > standardThreshold
then subtotal * 0.05 else 0.0);
Operation: Order.summarize(taxRate : Float, premiumThreshold : Float, standardThreshold : Float) : OrderSummary
// Composes subtotal, discount and tax into the result the caller sends back to the client.
create result;
set result.orderId = self.orderId;
local subtotal = self.calculateSubtotal();
local discount = self.calculateDiscount(subtotal, premiumThreshold, standardThreshold);
set result.subtotal = subtotal;
set result.discount = discount;
set result.tax = (subtotal - discount) * taxRate;
set result.total = subtotal - discount + result.tax;
Avoid
Operation: Order.summarize() : OrderSummary
create r;
set r.id = o.orderId;
local lt = apply element.price * element.quantity to o.items;
set r.st = reduce lt using element + nextElement if single use element;
set r.d = if o.customerType = "PREMIUM" then (if r.st > 500.0 then r.st * 0.1 else 0.0) else (if r.st > 1000.0 then r.st * 0.05 else 0.0);
set r.t = (r.st - r.d) * 0.08;
set r.tot = r.st - r.d + r.t;
set r.v = true if o.items.exists();
set r.v = false if not(o.items.exists());
Problems:
This is one monolithic operation doing validation + subtotal + discount + tax + total, so none of these pieces can be reused or tested independently. Abug in one concern (e.g. the discount tiers) can't be isolated without reading the entire script top to bottom.
|
Line(s) |
Remark |
|---|---|
|
|
Variable naming.
|
|
|
This assumes |
|
|
The entire discount rule is crammed onto one unreadable line with nested statements. |
|
|
This could just be This "is this order even valid" check happens last, after subtotal/discount/tax were already computed off. Validation needs to happen first (ideally in the diagram, gating whether this operation runs at all), not as an afterthought at the bottom. |