Client Actions, Server Actions, and Action Parameters
Key Takeaways
- Client Actions run in the browser and can manipulate UI variables and screen state but cannot directly contain Aggregates, SQL, or entity actions — they must call a Server Action for any database access.
- Server Actions run on the OutSystems server, have direct database access (Aggregates, entity actions, SQL), and auto-commit the transaction on success or roll back on unhandled exception.
- Input Parameters receive values from the caller at invocation; Output Parameters return typed results from a Server Action back to the caller; Local Variables are internal working storage reset on each call.
- GetUserId() returns the User Identifier of the currently logged-in user; NullIdentifier() returns an empty identifier used to test whether a variable is set or to signal create-via-CreateOrUpdate.
- Set a Server Action's Public property to Yes to expose it to other modules via Manage Dependencies; for shared validation logic, create one reusable Server Action and call it from every consumer instead of duplicating code.
Client Actions, Server Actions, and Action Parameters
Quick Answer: In OutSystems O11 Reactive Web Apps, a Client Action runs in the browser and can manipulate UI variables and screen state but cannot directly query the database. A Server Action runs on the server, has direct database access (Aggregates, entity actions, SQL), and returns results to the caller. Both accept Input Parameters, Server Actions declare Output Parameters, and both use Local Variables for internal state. Use a Client Action for UI event handling; use a Server Action whenever you need database reads or writes, transactional integrity, or reusable business logic invoked from multiple screens or modules.
Client Actions: Browser-Side Logic
In a Reactive Web App, a Client Action is compiled to JavaScript that runs in the browser. Client Actions are the default handlers for screen widget events — a Button's OnClick and a Link's click both wire to a Client Action. They can read and assign Local Variables and Client Variables, call other Client Actions, call Server Actions (the call crosses to the server and waits for the result), navigate using the Navigate built-in action, execute Refresh Data to re-run a Data Action, and show Feedback Message toasts.
Client Actions cannot directly contain Aggregates, SQL nodes, or entity actions (CreateRecord, UpdateRecord, DeleteRecord) because those require server-side database access. To read or write data, a Client Action must call a Server Action, which performs the DB work and returns results through Output Parameters. This boundary is the single most tested distinction in the Logic domain.
Server Actions: Server-Side Logic with Database Access
A Server Action executes entirely on the OutSystems server. It can contain Aggregates, SQL nodes, entity actions (CreateRecord, UpdateRecord, DeleteRecord, CreateOrUpdateRecord), and has access to the database transaction context. Server Actions are used for fetching, creating, updating, and deleting records; complex validation needing database lookups (e.g., does this SKU already exist); reusable business logic called from multiple screens; and transactional logic — if a Server Action raises an unhandled exception, all database changes roll back automatically.
To make a Server Action available to other modules, set its Public property to Yes; other modules then reference it via Manage Dependencies. A private Server Action (Public = No) is only callable within its own module.
Data Actions vs Server Actions
A Data Action is a special server-side action used to fetch data for a screen or Block. It supports caching through Cache in Minutes and has lifecycle events (OnAfterFetch) for post-fetch processing. Data Actions are the reactive-screen equivalent of the Traditional Web Preparation action. They are not general-purpose Server Actions; their job is screen and Block data provisioning, and the platform manages their execution and caching.
Input Parameters, Output Parameters, and Local Variables
Every action — Client or Server — works with three categories of data:
| Element | Scope | Set By | Purpose |
|---|---|---|---|
| Input Parameter | Passed in by the caller | Caller passes a value when invoking | Passes data into the action (e.g., a record Id to fetch) |
| Output Parameter | Returned to the caller | Action assigns a value before End | Returns results (e.g., the fetched record, a success boolean) — Server Actions |
| Local Variable | Internal to the action | Initialized within the action | Working storage during execution; reset on each call |
Input Parameters have a data type (Text, Integer, Decimal, Boolean, Date Time, Identifier, Structure, List) and can be Mandatory — the caller must supply a value or Service Studio flags an error. Output Parameters are typed; the End node returns their current values. Local Variables are typed, can have defaults, and hold intermediate computation results within the flow.
Built-in Functions
OutSystems provides built-in functions in expression editors. The most exam-relevant:
- GetUserId() — returns the User Identifier of the currently logged-in user. Use it to filter records by owner, audit who created or modified a record, or pass into CheckRole.
- NullIdentifier() — returns an empty Identifier value, used to test whether a variable is set or to signal create-via-CreateOrUpdate (NullIdentifier means no existing record, so create new).
- CheckRole(Role) — returns a boolean indicating whether the current user holds a specific role.
- GrantRole(Role, UserId) — grants a role to a user at runtime.
GetUserId runs wherever the containing action runs; in a Server Action it reads the server-side session — the correct usage for record ownership checks.
Reusable Actions and When to Use Which Type
For reusable logic (e.g., the same validation in multiple Server Actions), create a single Server Action containing the shared logic and call it from each consumer. The reusable Server Action receives inputs via Input Parameters and returns results via Output Parameters.
| Need | Use |
|---|---|
| React to a button click, show or hide UI, set a local variable | Client Action |
| Navigate to another screen | Client Action (Navigate) |
| Re-run a Data Action to refresh screen data | Client Action (Refresh Data) |
| Read or write database records | Server Action (Aggregates or entity actions) |
| Run validation that needs a database lookup | Server Action |
| Logic shared across screens or modules | Server Action (Public = Yes) |
| Transactional multi-step DB writes | Server Action (auto-commit, rollback on exception) |
A common exam trap: a Client Action that needs to update a record must call a Server Action — it cannot use entity actions directly. Another trap: GetUserId runs wherever the containing action runs, so for record ownership checks it belongs in a Server Action where the database is accessible, not in a Client Action.
Which OutSystems action type executes in the browser and can manipulate UI variables but cannot directly contain Aggregates or entity actions?
What does the OutSystems built-in function GetUserId() return?
A developer needs the same validation logic in multiple Server Actions across a module. What is the recommended OutSystems approach?