write-rules

Write Mendix rules — a special kind of microflow returning a Boolean or enumeration, callable only from a decision. Use when writing CREATE RULE, or deciding whether logic belongs in a rule or a micro

SKILL.md

GitHub
<!-- skill-index: generated by scripts/skill-index.py; make check-skill-index -->

Find it fast

sed -n '<from>,<to>p' SKILL.md one section rather than reading the file; ./mxcli syntax <topic> answers how do I write this for a fraction of either.

lines section
29-38 When to Use This Skill
39-52 When to Use a Rule vs a Microflow
53-67 Key Differences from Microflows
68-111 Syntax
112-129 Reading and managing rules
130-144 What a rule may not contain
145-155 Validation checklist
156-158 Rules (LIST/DESCRIBE/CREATE [OR MODIFY]/DROP/MOVE RULE)
<!-- /skill-index -->

Mendix Rule Skill

Guidance for writing Mendix rules in MDL. Mendix's own reference calls a rule "a special kind of microflow": it returns a Boolean or an enumeration, and it can only be used from a decision.

When to Use This Skill

  • Writing CREATE RULE statements
  • Deciding whether logic belongs in a rule or a microflow
  • Understanding what mxcli check refuses in a rule body and why

The mirrors are write-microflows and write-nanoflows — a rule is the third flavour and shares their body syntax exactly.

When to Use a Rule vs a Microflow

Scenario Use
One condition, evaluated from several decisions Rule
A named business condition the model should show by name Rule
Choosing one of several enumerated outcomes from input Rule
Anything that changes data Microflow
Anything the user sees (page, message, download) Microflow
Anything that talks to another system Microflow

Rule of thumb: a rule answers a question. The moment it needs to do something, it is a microflow.

Key Differences from Microflows

Aspect Microflow Rule
Return type Anything, including void Boolean or enumeration — mandatory
Called from Anywhere A decision, and nowhere else
Changes data Yes No
Talks to the client Yes No
Integration Yes No
Module-role security grant execute on microflow … None — a rule has no security to grant

That last row is not an mxcli omission. A rule document stores no AllowedModuleRoles, because a rule is never called on its own; it is reached through the microflow that evaluates it, and that microflow's security applies.

Syntax

mdl 1;
create or modify rule Sales.Rule_IsSolvent ($pCustomer: Sales.Customer)
returns Boolean
folder 'Rules'
begin
  return $pCustomer/Balance >= 0;
end;

An enumeration rule lets one decision fan out to several branches:

mdl 1;
create or modify rule Sales.Rule_Outcome ($pCustomer: Sales.Customer)
returns enum Sales.Outcome
begin
  if $pCustomer/Balance >= 0 then
    return Sales.Outcome.Approved;
  else
    return Sales.Outcome.Rejected;
  end if;
end;

Calling one — the only place a rule may be called:

mdl 1;
create or modify microflow Sales.MF_Screen ($pCustomer: Sales.Customer)
begin
  if Sales.Rule_IsSolvent(pCustomer = $pCustomer) then
    return;
  else
    return;
  end if;
end;

The argument names are the rule's parameter names, so Rule_IsSolvent(pCustomer = $pCustomer) reads the same way a microflow call does.

Reading and managing rules

mdl 1;
list rules;                  -- `list rules` is the same statement
list rules in Sales;
describe rule Sales.Rule_IsSolvent;   -- round-trippable MDL
drop rule Sales.Rule_IsSolvent;
move rule Sales.Rule_IsSolvent to folder 'Rules/Customer';

list microflows lists microflows only — not nanoflows, not workflows, and not rules. Each doctype has its own listing.

list callers of Sales.Rule_IsSolvent lists the microflows whose decisions evaluate it, and a microflow called from inside a rule's body is a normal reference: it will not be reported as dead code.

What a rule may not contain

mxcli check refuses these before the build, with the same function exec uses, so the two cannot disagree. Each was measured against mxbuild 11.13.0:

Written in a rule mxbuild says
create / change / delete / commit / rollback CE0009 "This action is not supported in rules."
show page, close page, show message, validation feedback, download CE0009
call web service CE0009
A void, String, Integer … return type CE0103 and CE0139 — the return type must be Boolean or an enumeration

A missing returns clause is refused too. For a microflow, void is a legitimate choice; for a rule it means the decision calling it has nothing to branch on.

Validation checklist

Before presenting a rule:

  • returns Boolean or returns enum Module.Enum is present
  • The body only reads — no create/change/delete/commit/rollback
  • Nothing in the body touches the client or another system
  • Every path returns a value of the declared type
  • The caller is a decision: if Module.Rule_Name(Param = $Value) then
  • mxcli check script.mdl -p app.mpr --references passes

Rules (LIST/DESCRIBE/CREATE [OR MODIFY]/DROP/MOVE RULE)

Mendix's "special kind of microflow" — returns Boolean or an enumeration, callable only from a decision. Handled as a third flow flavour beside microflows and nanoflows: its own semantic type, its own listing (list microflows stays microflow-only), the shared microflowBody, flow builder and describer. The document is the ten properties a Studio Pro rule stores, pinned against two reference rules (ako/TestApp, 11.13.0) — no AllowedModuleRoles (a rule is not independently callable, so there is no grant execute on rule) and no ReturnType despite gen declaring one beside MicroflowReturnType. Two keys only a reference document catches, both invisible to mx check: ExportLevel (Studio Pro writes "Hidden" on every rule) and Flows (written as the bare marker even when empty — a MandatoryLists entry). Rules are catalog objects and their bodies are walked for references, which together stop a microflow called only from a rule reading as dead. The body restrictions are refused at check time by the same function exec calls, each measured: create/change/delete/commit/rollback and client or web-service activities are CE0009, a non-Boolean/enum return is CE0103 + CE0139. Authoring is modelsdk-only; legacy refuses.