CREATE MICROFLOW
Synopsis
CREATE [ OR REPLACE ] MICROFLOW module.Name
[ ( DECLARE $param : type [, ...] ) ]
[ RETURN type ]
[ FOLDER 'path' ]
BEGIN
statements
END
Description
Creates a new microflow in the specified module. Microflows are the server-side logic building blocks in Mendix – they execute on the application server and have access to the full set of activities including database operations, external service calls, and security-sensitive actions.
If OR REPLACE is specified and a microflow with the same qualified name already exists, it is replaced. Otherwise, creating a microflow with an existing name is an error.
The microflow body consists of a sequence of statements enclosed in BEGIN ... END. Statements are executed in order, with control flow managed by IF, LOOP, WHILE, and RETURN constructs.
Microflow Parameters
Microflow parameters are declared in parentheses after the name. Each parameter has a name (prefixed with $), a colon, and a type. Parameters become variables available throughout the microflow body.
Return Type
If the microflow returns a value, specify RETURN type after the parameter list. The type can be any primitive type, an entity type, or a list type. Every execution path must end with a RETURN statement when a return type is declared.
Folder Placement
The optional FOLDER clause places the microflow in a subfolder within the module. Nested folders use / as separator. Missing folders are created automatically.
Activities
The following activities are available inside the microflow body.
Variable Declaration and Assignment
DECLARE $Var Type = value;
DECLARE $Entity Module.Entity;
DECLARE $List List of Module.Entity = empty;
SET $Var = expression;
Primitive types: String, Integer, Long, Decimal, Boolean, DateTime. Entity declarations do not use = empty. List declarations require = empty to initialize an empty list.
Object Operations
$Var = CREATE Module.Entity ( Attr1 = value1, Attr2 = value2 ) [ COMMIT [ WITHOUT EVENTS ] ] [ REFRESH ];
CHANGE $Entity ( Attr = value ) [ COMMIT [ WITHOUT EVENTS ] ] [ REFRESH ];
COMMIT $Entity [ WITHOUT EVENTS ] [ REFRESH ];
DELETE $Entity [ REFRESH ];
ROLLBACK $Entity [ REFRESH ];
CREATE instantiates a new object with initial attribute values. CHANGE modifies attributes on an existing object. COMMIT persists changes to the database – the before/after commit event handlers run unless you write WITHOUT EVENTS, matching Studio Pro’s default, and REFRESH updates client-side state. ROLLBACK reverts uncommitted changes to an object.
Every one of these modifiers is optional, and leaving one out always means Mendix’s own default – Commit: No and Refresh in client: No throughout, and With events: Yes on the standalone COMMIT. A bare statement therefore produces the same activity as dragging a fresh one onto the Studio Pro canvas.
Retrieval
-- Database retrieve with optional XPath constraint
RETRIEVE $Var FROM Module.Entity [ WHERE condition ] [ LIMIT n ];
-- Retrieve by association
RETRIEVE $List FROM $Parent/Module.AssocName;
RETRIEVE ... LIMIT 1 returns a single entity. Without LIMIT or with LIMIT greater than 1, it returns a list. Retrieve by association traverses an association from a known object.
Calls
$Result = CALL MICROFLOW Module.Name ( Param = $value );
$Result = CALL NANOFLOW Module.Name ( Param = $value );
$Result = CALL JAVA ACTION Module.Name ( Param = value );
Call another microflow, nanoflow, or Java action. Parameters are passed by name. The result can be assigned to a variable when the callee has a return type. If no return value is needed, omit the $Result = prefix.
UI Actions
SHOW PAGE Module.PageName ( $Param = $value );
CLOSE PAGE;
SHOW PAGE opens a page, passing parameters by name. CLOSE PAGE closes the current page.
Validation and Logging
VALIDATION FEEDBACK $Entity/Attribute MESSAGE 'message';
LOG INFO | WARNING | ERROR [ NODE 'name' ] 'message';
VALIDATION FEEDBACK adds a validation error to a specific attribute on an object. LOG writes to the application log at the specified level, optionally tagged with a log node name.
Execute Database Query
$Result = EXECUTE DATABASE QUERY Module.Connector.QueryName;
Executes a Database Connector query. The three-part name identifies the connector module, connection, and query. Supports DYNAMIC, parameters, and CONNECTION override.
Control Flow
IF condition THEN
statements
[ ELSE
statements ]
END IF;
LOOP $Item IN $List BEGIN
statements
END LOOP;
WHILE condition BEGIN
statements
END WHILE;
RETURN $value;
IF branches on a boolean expression. LOOP iterates over each item in a list. WHILE loops while a condition holds true. RETURN ends execution and returns a value (required when the microflow declares a return type).
Error Handling
-- Suffix on any activity (except EXECUTE DATABASE QUERY)
activity ON ERROR CONTINUE;
activity ON ERROR ROLLBACK;
activity ON ERROR {
handler_statements
};
Error handling is attached as a suffix to an individual activity. ON ERROR CONTINUE suppresses the error and continues. ON ERROR ROLLBACK rolls back the current transaction. ON ERROR { ... } executes custom error-handling logic.
Annotations
Annotations are placed before an activity to control visual appearance in the microflow editor:
@position(x, y) -- Canvas position
@start(x, y) -- Canvas position of the start event (first statement only)
@caption 'text' -- Custom caption
@color Green -- Background color
@annotation 'text' -- Visual note attached to next activity
@start positions the start event, which has no statement of its own, so it is
written on the first statement — the one the start flows into. It is optional:
omit it and the start is placed one spacing unit left of the first activity, on
that activity’s centre line, and a later rewrite re-derives it so it follows the
activities when they move.
A start that is not at that derived spot — one dragged somewhere in Studio Pro,
or written with @start — is treated as placed on purpose. It survives a rewrite
that does not mention it, and DESCRIBE emits an @start line for it so the
description reproduces the flow exactly. An explicit @start overrides both.
Parameters
module.Name- The qualified name of the microflow (
Module.MicroflowName). The module must already exist. $param : type- A parameter declaration. The name must start with
$. The type can be:- Primitive:
String,Integer,Long,Decimal,Boolean,DateTime - Entity:
Module.EntityName - List:
List of Module.EntityName - Enumeration:
Enumeration(Module.EnumName)
- Primitive:
RETURN type- The return type of the microflow. Same type options as parameters.
FOLDER 'path'- Optional folder path within the module. Nested folders use
/separator (e.g.,'Orders/Processing').
Examples
Simple microflow that creates and commits an object:
CREATE MICROFLOW Sales.ACT_CreateOrder
FOLDER 'Orders'
BEGIN
DECLARE $Order Sales.Order;
$Order = CREATE Sales.Order (
OrderDate = [%CurrentDateTime%],
Status = 'Draft'
);
COMMIT $Order;
SHOW PAGE Sales.Order_Edit ($Order = $Order);
RETURN $Order;
END;
Microflow with parameters and conditional logic:
CREATE MICROFLOW Sales.ACT_ApproveOrder
(DECLARE $Order: Sales.Order)
RETURN Boolean
BEGIN
IF $Order/Status = Sales.OrderStatus.Pending THEN
CHANGE $Order (Status = Sales.OrderStatus.Approved);
COMMIT $Order;
LOG INFO NODE 'OrderProcessing' 'Order approved';
RETURN true;
ELSE
VALIDATION FEEDBACK $Order/Status MESSAGE 'Only pending orders can be approved';
RETURN false;
END IF;
END;
Microflow with a loop over a retrieved list:
CREATE MICROFLOW Sales.ACT_DeactivateExpiredCustomers
RETURN Integer
FOLDER 'Scheduled'
BEGIN
DECLARE $Count Integer = 0;
RETRIEVE $Customers FROM Sales.Customer
WHERE [IsActive = true AND ExpiryDate < [%CurrentDateTime%]];
LOOP $Customer IN $Customers BEGIN
CHANGE $Customer (IsActive = false);
COMMIT $Customer;
SET $Count = $Count + 1;
END LOOP;
LOG INFO NODE 'Maintenance' 'Deactivated expired customers';
RETURN $Count;
END;
Microflow with error handling:
CREATE MICROFLOW Integration.ACT_SyncData
BEGIN
DECLARE $Result Integration.SyncResult;
$Result = CREATE Integration.SyncResult (
StartTime = [%CurrentDateTime%],
Status = 'Running'
);
COMMIT $Result;
$Result = CALL MICROFLOW Integration.SUB_FetchExternalData (
SyncResult = $Result
) ON ERROR {
CHANGE $Result (Status = 'Failed');
COMMIT $Result;
LOG ERROR NODE 'Integration' 'Sync failed';
};
CHANGE $Result (
Status = 'Completed',
EndTime = [%CurrentDateTime%]
);
COMMIT $Result;
END;
Microflow calling a Java action:
CREATE MICROFLOW MyModule.ACT_GenerateReport
(DECLARE $StartDate: DateTime, DECLARE $EndDate: DateTime)
RETURN String
BEGIN
DECLARE $Report String = '';
$Report = CALL JAVA ACTION MyModule.JA_GenerateReport (
StartDate = $StartDate,
EndDate = $EndDate
);
RETURN $Report;
END;
Using OR REPLACE to update an existing microflow:
CREATE OR REPLACE MICROFLOW Sales.ACT_CreateOrder
FOLDER 'Orders'
BEGIN
DECLARE $Order Sales.Order;
$Order = CREATE Sales.Order (
OrderDate = [%CurrentDateTime%],
Status = 'Draft',
CreatedBy = '[%CurrentUser%]'
);
COMMIT $Order;
RETURN $Order;
END;
See Also
CREATE NANOFLOW, DROP MICROFLOW, CREATE JAVA ACTION, DESCRIBE MICROFLOW, GRANT EXECUTE ON MICROFLOW