FDD Story Get Started Tutorial Docs Motivation Download GitHub

Repositories

ARO provides built-in in-memory repositories for storing and retrieving data. Repositories are automatically created when you store data using the naming convention <entity-repository> and support querying, updating, and observation.

Storing Data

Store entities into a repository using the Store action:

Create the <user: User> with {
    name: "Alice",
    email: "alice@example.com"
}.
Store the <user> into the <user-repository>.

The repository is automatically created on first use. Each stored entity receives a unique id if not already present.

Retrieving Data

Get All Entities

Retrieve the <all-users> from the <user-repository>.

Query by Field

Retrieve the <user> from the <user-repository> where id = <userId>.

Retrieve the <admins> from the <user-repository> where role = "admin".

Get First or Last

Retrieve the <latest: last> from the <message-repository>.
Retrieve the <oldest: first> from the <message-repository>.

Updating Data

Update the <user-repository> where id = <userId> with {
    status: "active",
    lastLogin: <now>
}.

Deleting Data

Delete from the <user-repository> where id = <userId>.

Repository Observers

React to repository changes with observer feature sets. Observers are triggered whenever data is stored, updated, or deleted.

Observer Pattern

(Log User Changes: user-repository Observer) {
    Extract the <action> from the <event: action>.
    Extract the <entity> from the <event: entity>.
    Log "User repository: " to the <console>.
    Log <action> to the <console>.
    Return an <OK: status> for the <observation>.
}

Conditional Observers with when Guard

Add a when clause to trigger observers only when a condition is met. Use <repository-name: count> to access the repository size.

(* Only triggers when message count exceeds 100 *)
(Cleanup Messages: message-repository Observer) when <message-repository: count> > 100 {
    Retrieve the <all-messages> from the <message-repository>.
    Extract the <keep-messages: 0-49> from the <all-messages>.
    Clear the <all> from the <message-repository>.
    Store the <keep-messages> into the <message-repository>.
    Return an <OK: status> for the <cleanup>.
}

The when guard is evaluated before the observer runs. If the condition is false, the observer is silently skipped. This prevents infinite loops when the observer modifies the same repository it observes.

The observer receives an event with:

Property Description
action "stored", "updated", or "deleted"
entity The affected entity
repository Repository name

Complete Example: User Management

api.aro

(createUser: User API) {
    Extract the <body> from the <request: body>.
    Create the <user: User> with {
        name: <body: name>,
        email: <body: email>,
        createdAt: <now>
    }.
    Store the <user> into the <user-repository>.
    Return a <Created: status> with <user>.
}

(listUsers: User API) {
    Retrieve the <users> from the <user-repository>.
    Return an <OK: status> with <users>.
}

(getUser: User API) {
    Extract the <id> from the <pathParameters: id>.
    Retrieve the <user> from the <user-repository> where id = <id>.
    Return an <OK: status> with <user>.
}

(deleteUser: User API) {
    Extract the <id> from the <pathParameters: id>.
    Delete from the <user-repository> where id = <id>.
    Return an <OK: status> for the <deletion>.
}

observers.aro

(Audit User Changes: user-repository Observer) {
    Extract the <action> from the <event: action>.
    Extract the <user> from the <event: entity>.

    Create the <audit-entry> with {
        action: <action>,
        userId: <user: id>,
        timestamp: <now>
    }.
    Store the <audit-entry> into the <audit-repository>.

    Return an <OK: status> for the <audit>.
}

Important Notes


← Templates | Data Pipelines →