Interaction Model
Interactions bring static pages to life. Momen’s interaction model is based on an Event-Driven mechanism:
- Trigger: Defines when to execute (e.g., button clicked, page loaded, scheduled time reached)
- Action: Defines what to do (e.g., update database, show toast, call API)
In Momen, there is a clear distinction between Frontend and Backend interactions:
- Frontend Interaction: Runs on the Client (Browser/Mobile), responding to user operations like clicks or swipes. It handles navigation, UI feedback, and calling backend services.
- Backend Interaction (Actionflow): Runs on the Server, handling complex business logic such as database operations, 3rd-party API calls, and scheduled tasks.
Frontend vs Backend
Take a shopping flow as an example: a user taps a product card, opens the detail page, and pays. As a developer, you break this into “when + what”:
- When the user clicks the product card view, run a Navigate to page action to open the matching product detail page.
- When the user clicks the payment button on the detail page, run a Call Actionflow action to securely create the order with a pending status on the server. When the Actionflow returns success, run the Payment action to complete the transaction.
Corresponding configuration:
- In the product card view’s Action panel, configure a Navigate to page action under On click, passing the target page (detail page) and parameters (product id).
- In the payment button’s Action panel, configure a Call Actionflow (Create order) action under On click to pass
product_idto the backend. In its On success branch, configure a Payment action with the order id and amount returned by the Actionflow.
Mapping user operations to configuration this way is the key to Momen’s interaction model.
Why Separate Frontend and Backend
The separation stems from fundamental differences in execution environments:
Security:
- Frontend code is publicly accessible and can be tampered with.
- Permission-related operations (e.g., assign roles) must run on the backend.
Data consistency:
- The frontend can close or lose network connection mid-process. Relying on it for multi-step data mutations can leave partial updates.
- Backend database operations provide ACID transactions, ensuring the atomicity of complex mutations.
- Multiple mutations that must succeed or fail together (e.g., order creation + inventory deduction) belong in a backend Actionflow. (Third-party API calls within a flow cannot be automatically rolled back.)
Performance:
- Keep computation close to the data to reduce transfer overhead and latency.
- Run complex calculations, scheduled tasks, and batch processing on the server.
Logic Execution Boundaries
Frontend-only (client-side actions):
- UI operations (e.g., show/hide elements, page navigation, scroll control)
- Real-time input validation (e.g., format checking)
- Client-side state management (e.g., set page variable)
Backend-only (server-side Actionflows):
- Permission operations (e.g., assign/remove roles)
- Multi-step transactional workflows (e.g., order processing with inventory deduction)
- Scheduled tasks (e.g., daily report generation, data cleanup)
- Webhook callback handling
- Payment processing (financial operations must be server-side)
Either side:
- Database operations (CRUD)
- API calls to third-party services
- AI agent invocations
For these, single-step actions can run on either side. But multi-step operations should run on the backend to ensure data consistency. Also consider RPS (requests per second) limits when calling from the frontend.
Frontend Interactions
Frontend interactions are configured directly in the component’s properties panel.
Trigger Types
Frontend triggers can be categorized into three types based on when they fire:
User Interaction Triggers:
- Respond to direct user actions (e.g., click, hover, scroll into viewport).
- Used to respond to user behavior.
Parent-Child Component Trigger Order: When a parent container and a child component visually overlap and both have the same trigger configured, the execution mechanism varies depending on the specific trigger type (e.g., “On Click” behaves differently from “On Hover”). For detailed rules, refer to On Click and On Hover in the Triggers Reference.
State Change Triggers:
- Respond to component state changes (e.g., input value change, video play/pause).
- Used to synchronize logic with data or status updates (e.g., validating a form immediately upon value change, triggering dependent dropdowns, or showing a ‘replay’ button when a video ends).
Lifecycle Triggers:
- Triggered automatically at specific lifecycle stages, such as On App Launch, On Page Load, and On Page Unload.
- Commonly used for initializing data or cleaning up resources.
For the complete list of triggers and their use cases, refer to: Triggers Reference.
Available Actions
Frontend actions execute in the browser or mobile app and fall into four main categories:
- UI & Local Operations:
- Navigation: navigate to page, go back, open URL, etc.
- Toast & Modal: show toast, open/close modals.
- Component: set input values, scroll, switch views, play/pause media, etc.
- Operating System / Hardware Interaction: upload/download files, get location, share, clipboard, etc.
- State Management:
- Variable Control: set/reset page variables, client variables, etc.
- Data Source: refresh data sources, etc.
- Backend Calls:
- Account: sign up, sign in, sign out, reset password, etc.
- Database: insert, update, delete data, transaction
- Actionflow: trigger backend workflows (e.g., payment processing, order creation)
- API: call pre-configured APIs. (When built-in actions cannot meet your needs, APIs are the tool to connect external services, such as querying weather, translating text, connecting external hardware, and other functionality. For more details, refer to: API Integration)
- AI Agent: start/continue/stop conversations with AI agents
- Payment: initiate payments, process refunds
- Logic Control:
- Condition: condition branch processing
- For Each: execute actions for each element in a collection
Synchronous vs Asynchronous Actions
It’s important to distinguish between synchronous and asynchronous actions in frontend interactions:
-
Synchronous Actions are executed instantly. These actions cannot be interrupted, and nothing can be inserted between them. Typical examples include:
show toastshow modalnavigate to
These actions immediately update the UI or change the application state, and their completion is assumed as soon as they are called.
-
Asynchronous Actions involve a process with a beginning, waiting period, and end—they may require time to finish, and support success/failure branching. Examples include:
- Backend operations like
modify db - Triggering an
Actionflow - API requests
With asynchronous actions, the next step often depends on the result (success or failure), and you can define different follow-up actions for each outcome.
- Backend operations like
Full list: Frontend Actions Reference.
Execution Flow
When configuring frontend interactions, multiple actions can be combined. Whether to execute sequentially or in parallel depends on how you nest actions.
Sequential Execution
When actions are nested within the On success or On failure branch of a previous action, they execute sequentially.
Note: Not all actions support On success/On failure branches. Actions that involve operations requiring a response (e.g., database, API, Actionflow, account) have these branches, while immediate UI operations do not.
Trigger
└─ Action A
├─ On success:
│ └─ Action B
│ └─ On success:
│ └─ Action C
└─ On failure:
└─ Action D (Error handling)Execution Process:
- After the trigger fires, execute action A
- When A completes successfully, execute action B
- When B completes successfully, execute action C
- When A fails (e.g., returns error, network disconnect, timeout), execute action D
Use Case: When subsequent actions depend on the result of previous actions (e.g., submit an order → wait for success and get the returned order_id → navigate to the detail page with that ID)
Parallel/Asynchronous Execution
When multiple actions are at the same level (not nested within success/failure branches), they are configured to execute asynchronously. They start in sequence, but do not wait for the previous one to complete before starting the next one.
Trigger
├─ Action A
├─ Action B
└─ Action CExecution Process:
- After the trigger fires, A, B, and C start executing in sequence (A, then B, then C).
- If an action is asynchronous, the flow does not wait for it to complete; it immediately starts the next action.
- Start order is guaranteed, but completion order is not - actions will start strictly in the configured order, but asynchronous actions may complete in any order.
- Error isolation - If action A encounters an error (e.g., request timeout), actions B and C will still be executed.
Use Case: When actions are independent and you don’t need to wait for their results. Like showing a notification, then refreshing a list, then navigating to a page.
Race Condition Risk: If asynchronous actions access or modify the same data concurrently, the final result is unpredictable. Avoid configuring actions to execute asynchronously when they have data dependencies.
Comprehensive Example: Combining Sequential and Parallel
Scenario: User clicks submit button after filling out a form.
Button "On Click"
└─ Call Actionflow "submit_order"
├─ On success:
│ ├─ Show Toast "Order submitted successfully!"
│ ├─ Navigate to "order_list"
│ └─ Refresh order list
└─ On failure:
└─ Show Toast "Submission failed"Execution Process Explanation:
- Trigger: Button’s “On Click”.
- Action 1 (Sequential wait): Trigger “Call Actionflow”, pass form data to backend, and wait for the Actionflow to complete.
- Based on Action 1’s result:
- If successful (Asynchronous execution): Configure three sibling actions (show success toast, navigate back, refresh list), they will start in sequence without waiting for each other.
- If failed (Sequential execution): Only show error toast.
Note: Since Toast, navigation, and refresh are configured as parallel asynchronous execution at the same level, the page will navigate immediately, and the Toast may not have time to display. If you need to ensure users see the notification, you should nest the navigation action under the “On success” branch of the Toast action.
This example demonstrates:
- Sequential / Synchronous Execution: Wait for Actionflow to complete first.
- Asynchronous / Parallel Execution: Multiple sibling UI actions execute without waiting for each other after success.
- Error Handling: Execute different logic branches on failure.
Backend Logic (Actionflows)
Backend logic are configured in the Actionflow panel. Actionflows run on the server and support multi-step business logic orchestration. Once configured, they can be called anytime.
Trigger Types
Actionflows can be triggered in the following ways:
Manual Trigger (Called by Frontend):
- Invoked by frontend “Call Actionflow” actions to handle user requests (e.g., form submission, payment processing).
- Can pass inputs and return execution results.
System Trigger (Automatically triggered, no user action required):
- Scheduled Tasks (Cron): Automatically execute according to a schedule, for periodic tasks (e.g., daily report generation, data cleanup).
- Webhook: Receive HTTP callbacks from external systems, for system integration (e.g., payment gateway callbacks, third-party order sync).
- Data Changes: Automatically triggered by database changes, useful for automated data syncing or cascading updates (e.g., assign initial points when new user registers, sync data to external systems).
For complete list of triggers and their use cases, refer to: Triggers Reference.
Available Nodes
Actionflows are where you implement complex logic and orchestrate multi-step processes. You do that by connecting and configuring different nodes. Common node types include:
Database Operations:
- Insert, read, update, delete data (Database CRUD)
Integrations:
- Call APIs
- Run other Actionflows
- Run AI Agents
Logic Operations:
- Condition
- For Each
- While Loop
Privileged Operations (Backend-only):
- Permission Operations (e.g., assign/remove roles)
- Backend Code Execution (Code Block)
Others:
- Get user information (e.g., account ID)
- File processing (save images, videos, files, etc.)
For the complete list of node types, refer to: Actionflow Nodes Reference. How to build an Actionflow, refer to: Building Actionflows.
Actionflow Execution Modes
When creating an Actionflow, you must choose its execution mode:
| Mode | Response | Transaction | Timeout Limit | Use Case |
|---|---|---|---|---|
| Synchronous | Caller waits for result | Database operations support ACID transactions with rollback support. Other operations follow their own mechanisms | Entire flow bounded by plan cap; gateway may error at ~60s (details) | e.g., Inventory tracking, Payment processing |
| Asynchronous | Returns task ID immediately. Caller does not wait. | Not transactional | Each node bounded by plan cap; no global flow limit (details) | Long-running tasks (e.g., AI agent execution, Video generation) |
Currently, the AI node must be used in asynchronous execution mode.
Example: Payment Webhook Processing Actionflow
Scenario: Backend receives payment result callback from Stripe.
Configuration:
- Trigger: Webhook
- Variables: status (Text), message (Text)
- Outputs: status (Text), message (Text)
Node Flow:
1. [Code Block Node] extract_webhook_data
Function: Extract webhook data
Output: payment_status, order_id, payment_found
2. [Condition Node] check_payment_found
Condition: payment_found = true
├─ TRUE branch (payment record exists):
│ 3. [Condition Node] check_payment_status
│ Condition: payment_status = "success"
│
│ ├─ TRUE branch (payment successful):
│ │ 4. [Database Query Node] query_payment
│ │ Query: payment_record
│ │ Where: order_id = extract_webhook_data.order_id
│ │ Output: account_id
│ │
│ │ 5. [Database Update Node] update_account
│ │ Update: account
│ │ Where: account_id = query_payment.account_id
│ │ Update: is_member = true
│ │
│ │ 6. [Set Variable Node] set_success
│ │ Set: status = "Payment Successful"
│ │
│ │ 7. [Set Variable Node] set_message
│ │ Set: message = "Membership activated"
│ │
│ └─ FALSE branch (payment failed):
│ 8. [Set Variable Node] set_failed_status
│ Set: status = "Payment Failed"
│
│ 9. [Set Variable Node] set_failed_message
│ Set: message = "Payment failed, membership not activated"
│
└─ FALSE branch (order not found):
10. [Set Variable Node] set_error_status
Set: status = "Order Not Found"
11. [Set Variable Node] set_error_message
Set: message = "Order not found, please place order again"
12. [Output Node] Return result
Output: {status, message}Action Results and Data Transfer
Action Results are output data produced by actions or nodes during execution. They are part of the Context data.
Beyond action results, the context also includes environmental data (e.g., Current User, Current Time, Current Page, Current Component). For details on environmental context data, see Query and Bind Data.
This section focuses on how actions produce results and how subsequent actions consume them.
Core Principles:
- Unidirectional Transfer: Data flows from earlier actions to later actions only
- Execution Order Matters: Only sequential actions (not parallel) can access previous results
- Data Scope (Branch Isolation): Action results have local scope - data created inside a branch (Condition/Loop) only exists within that branch.
- Inside a Loop branch, the system automatically injects a local
Current Itemcontext for inner nodes to reference the current iteration. - To access or pass data out of the branch, you must use a variable with global scope (Page/Client variable for frontend, Actionflow variable for backend) initialized outside the loop and updated inside.
- Inside a Loop branch, the system automatically injects a local
Accessing Execution Results
General Output Rule: Whether configuring Frontend Actions or Backend Nodes, the rule for producing results is identical: Only operations that query, mutate, or process data generate output results (e.g., Database CRUD, API calls, Account operations, Code blocks). Operations that purely control UI, routing, or internal logic flow (e.g., Navigation, Show toast, Condition, Loop, Set variable) do not produce results.
Data Binding Paths: When configuring subsequent steps, you can bind data using the following paths:
- Frontend Actions:
Context→Action results→Action name→Field name- Example: The first step “Call Actionflow” returns an Order ID. In the second step “Navigate to page”, you can directly select this Order ID from the “Action results” in the Context as a page parameter.
- Backend Actionflows:
Actionflow data→Node name→Field name- Example: The first step “API Request” retrieves weather information. In the second step “Update Database”, you can read the temperature data from the “Actionflow data” of that API node and write it into the database.
For complete output field schemas of specific actions/nodes, refer to: Actionflow Nodes Reference and Frontend Actions Reference.