Skip to content

Guide Actions

Kris Simon edited this page Mar 1, 2026 · 10 revisions

Actions

Actions are the verbs of ARO. They describe what operation to perform on data. This chapter covers all built-in actions and how to use them effectively.

Action Categories

ARO actions are organized by their semantic role - the direction of data flow:

Role Direction Purpose
REQUEST External → Internal Bring data into the feature set
OWN Internal → Internal Transform data within the feature set
RESPONSE Internal → External Send results back
EXPORT Internal → External Publish or persist data

REQUEST Actions

These actions bring data from external sources into your feature set.

Extract

Pull data from a structured source:

Extract the <user-id> from the <request: parameters>.
Extract the <body> from the <request: body>.
Extract the <email> from the <user: email>.
Extract the <items> from the <order: lineItems>.

Common Sources:

  • <request: parameters> - URL path parameters
  • <request: query> - Query string parameters
  • <request: body> - Request body
  • <request: headers> - HTTP headers
  • <event: ...> - Event data
  • Any variable with properties

List Element Access

Extract specific elements from lists using result specifiers:

(* Split a string and access parts *)
Split the <parts> from the <csv-line> by /,/.
Extract the <first-part: first> from the <parts>.
Extract the <last-part: last> from the <parts>.

(* Numeric index (0 = last, 1 = second-to-last) *)
Extract the <item: 0> from the <list>.    (* last element *)
Extract the <item: 1> from the <list>.    (* second-to-last *)

(* Range - extract consecutive elements *)
Extract the <subset: 2-5> from the <list>.

(* Pick - extract specific elements *)
Extract the <selection: 0,3,7> from the <list>.
Specifier Returns
first First element
last Last element
0 Last element (reverse indexing)
n Element at position (count - 1 - n)
2-5 Array of elements 2, 3, 4, 5
0,2,4 Array of elements at indices 0, 2, 4

Retrieve

Fetch data from a repository or data store:

Retrieve the <user> from the <user-repository>.
Retrieve the <user> from the <user-repository> where id = <user-id>.
Retrieve the <orders> from the <order-repository> where status = "pending".
Retrieve the <products> from the <product-repository> where category = <category>.

With Conditions:

Retrieve the <user> from the <user-repository>
    where email = <email> and active = true.

Request

Make HTTP requests with full control over method, headers, body, and timeout:

(* Simple GET request *)
Request the <response> from the <api-url>.

(* POST request *)
Request the <result> to the <api-url> with <data>.

(* With config object for custom headers, method, timeout *)
Request the <response> from the <api-url> with {
    method: "POST",
    headers: { "Content-Type": "application/json", "Authorization": "Bearer token" },
    body: <data>,
    timeout: 60
}.

Config options: method (GET/POST/PUT/DELETE/PATCH), headers (map), body (string/map), timeout (seconds).

Read

Read from files:

Read the <content> from the <file: "./data.txt">.
Read the <config: JSON> from the <file: "./config.json">.
Read the <data: bytes> from the <file: "./image.png">.

Parse

Parse structured data:

Parse the <config: JSON> from the <json-string>.
Parse the <data: XML> from the <xml-string>.
Parse the <date> from the <date-string>.

OWN Actions

These actions create or transform data within your feature set.

Create

Create new data structures:

Create the <user> with <user-data>.
Create the <response> with { message: "Success", code: 200 }.
Create the <order> with {
    items: <items>,
    total: <total>,
    customer: <customer-id>
}.

Compute

Perform calculations:

Compute the <total> for the <items>.
Compute the <hash> for the <password>.
Compute the <tax> for the <subtotal>.
Compute the <average> for the <values>.

Transform

Convert or map data:

Transform the <dto> from the <entity>.
Transform the <response> from the <data>.
Transform the <updated-user> from the <user> with <updates>.
Transform the <formatted-date> from the <date>.

Validate

Check data against rules:

Validate the <user-data> for the <user-schema>.
Validate the <email> for the <email-pattern>.
Validate the <order> for the <order-rules>.

Validation can fail, which should be handled:

Validate the <input> for the <schema>.
Return a <BadRequest: status> with <validation: errors> when <validation> is failed.

Compare

Compare values:

Compare the <password-hash> against the <stored-hash>.
Compare the <signature> against the <expected-signature>.
Compare the <version> against the <minimum-version>.

Set

Assign a value:

Set the <status> to "active".
Set the <count> to 0.
Set the <timestamp> to <current-time>.

Configure

Set configuration values:

Configure the <timeout> with 30.
Configure the <retry-limit> with 3.
Configure the <debug-mode> with true.

RESPONSE Actions

These actions send results back from your feature set.

Return

Return a result with status:

(* Success responses *)
Return an <OK: status> with <data>.
Return a <Created: status> with <resource>.
Return a <NoContent: status> for the <deletion>.
Return an <Accepted: status> for the <async-operation>.

(* Error responses *)
Return a <BadRequest: status> with <errors>.
Return a <NotFound: status> for the <missing: resource>.
Return a <Forbidden: status> for the <unauthorized: access>.
Return an <Unauthorized: status> for the <invalid: credentials>.

Status Codes:

Status HTTP Code Use Case
OK 200 Successful GET, PUT, PATCH
Created 201 Successful POST creating resource
Accepted 202 Async operation started
NoContent 204 Successful DELETE
BadRequest 400 Invalid input
Unauthorized 401 Missing/invalid auth
Forbidden 403 Insufficient permissions
NotFound 404 Resource not found
Conflict 409 Resource conflict
InternalError 500 Server error

Throw

Throw an error:

Throw a <ValidationError> for the <invalid: input>.
Throw a <NotFoundError> for the <missing: user>.
Throw an <AuthenticationError> for the <invalid: token>.

EXPORT Actions

These actions publish data or send to external systems.

Store

Save to a repository:

Store the <user> into the <user-repository>.
Store the <order> into the <order-repository>.
Store the <log-entry> into the <audit-log>.

Publish

Make variables globally available:

Publish as <current-user> <user>.
Publish as <app-config> <config>.
Publish as <connection-pool> <pool>.

Published variables can be accessed from any feature set.

Log

Write to logs:

Log "User logged in" to the <console>.
Log <error> to the <console>.
Log <details> to the <audit-log>.

Send

Send data to external destinations:

Send the <email> to the <user: email>.
Send the <notification> to the <push-service>.
Send the <message> to the <queue>.
Send the <data> to the <connection>.

Emit

Emit domain events:

Emit a <UserCreated: event> with <user>.
Emit an <OrderPlaced: event> with <order>.
Emit a <PaymentProcessed: event> with <payment>.

Write

Write to files:

Write the <content> to the <file: "./output.txt">.
Write the <data: JSON> to the <file: "./data.json">.

Delete

Remove data:

Delete the <user> from the <user-repository> where id = <user-id>.
Delete the <file: "./temp.txt">.
Delete the <sessions> from the <session-repository> where expired = true.

Notify

Send a notification to a recipient. Works with single objects or collections — when given a collection, dispatches one notification per item:

(* Single recipient *)
Notify the <user> with "Your order has been shipped.".

(* Collection dispatch - one notification per subscriber *)
Notify the <subscribers> with "System maintenance tonight.".

Notification handlers use the NotificationSent Handler pattern:

(Send Welcome Email: NotificationSent Handler) {
    Extract the <user> from the <event: user>.
    Send the <email> to the <user: email>.
    Return an <OK: status> for the <notification>.
}

Handler Guards:

Add a when clause to filter which recipients trigger the handler. The recipient's fields are available directly in the condition:

(* Only handle adults *)
(Send Adult Content: NotificationSent Handler) when <age> >= 18 {
    Extract the <user> from the <event: user>.
    Log "Notified adult user" to the <console>.
    Return an <OK: status> for the <notification>.
}

(* Only handle premium users *)
(Send Premium Alert: NotificationSent Handler) when <tier> = "premium" {
    Extract the <user> from the <event: user>.
    Send the <priority-email> to the <user: email>.
    Return an <OK: status> for the <notification>.
}

If the guard condition is false, the handler is silently skipped.

Choosing Between Store, Emit, and Publish

Three actions make data available outside your feature set. Use this guide to pick the right one:

Decision Matrix

┌─────────────────────────────────────────────────────────┐
│  Do you need to...                                      │
├─────────────────────────────────────────────────────────┤
│  Persist data for later retrieval?      → Use Store   │
│  Trigger handlers in other feature sets? → Use Emit   │
│  Share a value without triggering logic? → Use Publish│
└─────────────────────────────────────────────────────────┘

Comparison

Aspect Store Emit Publish
Target Repository Event bus Global registry
Triggers Repository observers Event handlers Nothing
Data lifespan Persistent (app lifetime) Transient (handler execution) Persistent (app lifetime)
Access pattern Retrieve later Extract in handler Direct variable access
Use case CRUD data, audit logs Reactive workflows, sagas Shared config, singletons

When to Use Each

Store - Data you need to query later:

  • User records, orders, messages
  • Audit logs
  • Any data that needs filtering or retrieval

Emit - Reactive communication between feature sets:

  • Domain events (UserCreated, OrderPlaced)
  • Triggering side effects (send email, update inventory)
  • Building event chains/sagas

Publish - Rarely needed; shared computed values:

  • Application configuration loaded once
  • Connection pools or service instances
  • Values needed by multiple feature sets without triggering logic

Anti-patterns

Using Emit for persistence:

(* BAD - events are transient *)
Emit a <UserData: event> with <user>.
(* Later: can't retrieve user data *)

(* GOOD - store for persistence *)
Store the <user> into the <user-repository>.

Using Publish for reactive communication:

(* BAD - no handler triggered *)
Publish as <new-user> <user>.

(* GOOD - triggers handlers *)
Emit a <UserCreated: event> with <user>.

For a detailed guide with complete examples, see Chapter 6A: Export Actions in the Language Guide.

Terminal Actions

These actions enable interactive terminal UIs.

Prompt

Ask the user for text input:

Prompt the <name> for "Enter your name: ".
Prompt the <password> for "Password: ".
Prompt the <answer> for <question>.

Select

Present a selection menu and capture the choice:

Create the <colors> with ["Red", "Green", "Blue"].
Select the <color> from the <colors> with "Choose a color".

Create the <actions> with ["View", "Edit", "Delete"].
Select the <action> from the <actions> with "What would you like to do?".

Clear

Clear the terminal screen:

Clear the <terminal>.

Use Clear to refresh the display between menu screens or after displaying output.

Full terminal menu example:

(Application-Start: Task Manager) {
    Create the <tasks> with [].
    Keepalive the <application> for the <events>.
    Return an <OK: status> for the <startup>.
}

(Show Menu: Application Handler) {
    Clear the <terminal>.
    Create the <menu-items> with ["Add Task", "List Tasks", "Exit"].
    Select the <choice> from the <menu-items> with "Task Manager".
    Return an <OK: status> with <choice>.
}

Service Actions

These actions interact with runtime services.

Start

Start a service:

Start the <http-server> on port 8080.
Start the <scheduler>.
Start the <background-worker>.

Stop

Stop a service:

Stop the <http-server>.
Stop the <scheduler>.
Stop the <background-worker>.

Watch

Monitor a directory:

Watch the <directory: "./uploads"> as <file-monitor>.
Watch the <directory: "./config"> as <config-watcher>.

Listen

Listen for connections:

Listen on port 9000 as <socket-server>.

Connect

Connect to a service:

Connect to <host: "localhost"> on port 5432 as <database>.
Connect to <host: "redis.local"> on port 6379 as <cache>.

Close

Close connections:

Close the <database-connections>.
Close the <connection>.

Call

Make API calls:

Call the <result> via <UserAPI: POST /users> with <user-data>.
Call the <response> via <PaymentAPI: POST /charge> with <payment>.

Broadcast

Send to all connections:

Broadcast the <message> to the <socket-server>.

Action Patterns

Extract-Process-Return

Common pattern for request handlers:

(POST /users: User API) {
    (* Extract *)
    Extract the <user-data> from the <request: body>.

    (* Process *)
    Validate the <user-data> for the <user-schema>.
    Create the <user> with <user-data>.
    Store the <user> into the <user-repository>.

    (* Return *)
    Return a <Created: status> with <user>.
}

Retrieve-Transform-Return

Pattern for GET requests:

(GET /users/{id}: User API) {
    (* Retrieve *)
    Extract the <user-id> from the <request: parameters>.
    Retrieve the <user> from the <user-repository> where id = <user-id>.

    (* Transform (optional) *)
    Transform the <user-dto> from the <user>.

    (* Return *)
    Return an <OK: status> with <user-dto>.
}

Extract-Emit Pattern

Pattern for event-driven updates:

(POST /orders: Order API) {
    Extract the <order-data> from the <request: body>.
    Create the <order> with <order-data>.
    Store the <order> into the <order-repository>.

    (* Emit for other handlers *)
    Emit an <OrderCreated: event> with <order>.

    Return a <Created: status> with <order>.
}

Next Steps

Clone this wiki locally