-
Notifications
You must be signed in to change notification settings - Fork 0
Guide 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.
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 |
These actions bring data from external sources into your feature set.
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
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 |
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.
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 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 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>.
These actions create or transform data within your feature set.
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>
}.
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>.
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>.
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 values:
<Compare> the <password-hash> against the <stored-hash>.
<Compare> the <signature> against the <expected-signature>.
<Compare> the <version> against the <minimum-version>.
Assign a value:
<Set> the <status> to "active".
<Set> the <count> to 0.
<Set> the <timestamp> to <current-time>.
Set configuration values:
<Configure> the <timeout> with 30.
<Configure> the <retry-limit> with 3.
<Configure> the <debug-mode> with true.
These actions send results back from your feature set.
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 an error:
<Throw> a <ValidationError> for the <invalid: input>.
<Throw> a <NotFoundError> for the <missing: user>.
<Throw> an <AuthenticationError> for the <invalid: token>.
These actions publish data or send to external systems.
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>.
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.
Write to logs:
<Log> "User logged in" to the <console>.
<Log> <error> to the <console>.
<Log> <details> to the <audit-log>.
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 domain events:
<Emit> a <UserCreated: event> with <user>.
<Emit> an <OrderPlaced: event> with <order>.
<Emit> a <PaymentProcessed: event> with <payment>.
Write to files:
<Write> the <content> to the <file: "./output.txt">.
<Write> the <data: JSON> to the <file: "./data.json">.
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.
Three actions make data available outside your feature set. Use this guide to pick the right one:
┌─────────────────────────────────────────────────────────┐
│ 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>│
└─────────────────────────────────────────────────────────┘
| 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 |
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
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.
These actions interact with runtime services.
Start a service:
<Start> the <http-server> on port 8080.
<Start> the <scheduler>.
<Start> the <background-worker>.
Stop a service:
<Stop> the <http-server>.
<Stop> the <scheduler>.
<Stop> the <background-worker>.
Monitor a directory:
<Watch> the <directory: "./uploads"> as <file-monitor>.
<Watch> the <directory: "./config"> as <config-watcher>.
Listen for connections:
<Listen> on port 9000 as <socket-server>.
Connect to a service:
<Connect> to <host: "localhost"> on port 5432 as <database>.
<Connect> to <host: "redis.local"> on port 6379 as <cache>.
Close connections:
<Close> the <database-connections>.
<Close> the <connection>.
Make API calls:
<Call> the <result> via <UserAPI: POST /users> with <user-data>.
<Call> the <response> via <PaymentAPI: POST /charge> with <payment>.
Send to all connections:
<Broadcast> the <message> to the <socket-server>.
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>.
}
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>.
}
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>.
}
- Variables and Data Flow - How data flows through actions
- Control Flow - Conditional execution
- Events - Event-driven patterns
Fundamentals
- The Basics
- Feature Sets
- Actions
- Variables
- Type System
- Control Flow
- Error Handling
- Computations
- Dates
- Concurrency
Runtime & Events
I/O & Communication
Advanced