-
Notifications
You must be signed in to change notification settings - Fork 0
Start With ARO
This guide will walk you through creating your first ARO application: a simple "Hello World" API server.
ARO (Action-Result-Object) is a domain-specific language for building business applications. It uses natural language-like syntax to express business logic as a series of actions.
Key concepts:
-
Contract-First: Your API is defined in an
openapi.yamlfile before any code - Feature Sets: Business logic is organized into named feature sets
- Event-Driven: Feature sets are triggered by events (HTTP requests, custom events, etc.)
-
Natural Syntax: Code reads like English:
Action the <result> for the <object>
An ARO application is a directory containing .aro files and an openapi.yaml contract:
HelloWorldAPI/
├── openapi.yaml ← API contract (required for HTTP)
├── main.aro ← Application entry point
└── hello.aro ← Request handler
Every ARO HTTP application starts with an openapi.yaml file. This is your contract - it defines what endpoints your API has.
openapi.yaml:
openapi: 3.0.3
info:
title: Hello World API
description: A simple API that returns "Hello World"
version: 1.0.0
servers:
- url: http://localhost:8000
description: Local development server
paths:
/hello:
get:
operationId: sayHello # ← This name maps to an ARO feature set
summary: Say Hello
description: Returns a friendly "Hello World" greeting
responses:
'200':
description: Successful response with greeting
content:
application/json:
schema:
$ref: '#/components/schemas/HelloResponse'
components:
schemas:
HelloResponse:
type: object
properties:
message:
type: string
example: Hello World
required:
- messageKey Point: The operationId: sayHello is crucial. ARO uses this to route requests to the correct feature set.
Every ARO application needs exactly ONE Application-Start feature set. This is where your application begins.
main.aro:
(* Application Entry Point *)
(Application-Start: Hello World API) {
(* Log a startup message *)
Log "Hello World API starting..." to the <console>.
(* Start the HTTP server on port 8000 *)
Start the <http-server> on <port> with 8000.
(* Log ready message *)
Log "Server running at http://localhost:8000" to the <console>.
(* Keep the application running to process HTTP requests *)
Keepalive the <application> for the <events>.
(* Return OK to indicate successful startup *)
Return an <OK: status> for the <startup>.
}
(* Optional: Handle graceful shutdown *)
(Application-End: Success) {
Log "Shutting down..." to the <console>.
Stop the <http-server> for the <application>.
Return an <OK: status> for the <shutdown>.
}
| Element | Meaning |
|---|---|
(* ... *) |
Comment |
(Name: Activity) { } |
Feature set definition |
Verb |
The action verb (what to do) |
<result: qualifier> |
The result with optional qualifier |
for the <object> |
The target of the action |
with "value" |
Additional data |
The request handler is a feature set whose name matches the operationId from your OpenAPI contract.
hello.aro:
(* Request Handler for GET /hello *)
(sayHello: Hello API) {
(* Create the greeting message *)
Create the <greeting> with "Hello World".
(* Return an OK response with the greeting *)
Return an <OK: status> with <greeting>.
}
Important: The feature set name sayHello must exactly match the operationId in your OpenAPI contract. This is how ARO knows which code handles which endpoint.
Run your application directly without compilation:
# From the project root
aro run ./Examples/HelloWorldAPIYou should see:
Hello World API starting...
Server running at http://localhost:8000
Open a new terminal and test with curl:
curl http://localhost:8000/helloExpected response:
{"message": "Hello World"}ARO can compile your application to a native binary for production deployment.
aro check ./Examples/HelloWorldAPIThis validates all .aro files without running them.
aro compile ./Examples/HelloWorldAPIThis produces a compiled report showing the structure of your application.
aro build ./Examples/HelloWorldAPIThis creates a native executable in your application directory.
┌─────────────────┐
│ openapi.yaml │ ← Defines: GET /hello → operationId: sayHello
└────────┬────────┘
│
▼
┌─────────────────┐
│ ARO Runtime │ ← Loads contract, starts HTTP server
└────────┬────────┘
│
▼
┌─────────────────┐
│ HTTP Request │ ← GET /hello
│ arrives │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Route Registry │ ← Matches /hello → sayHello
└────────┬────────┘
│
▼
┌─────────────────┐
│ sayHello │ ← Feature set executes
│ Feature Set │
└────────┬────────┘
│
▼
┌─────────────────┐
│ HTTP Response │ ← {"message": "Hello World"}
└─────────────────┘
| Concept | Description |
|---|---|
| Contract-First | Define your API in openapi.yaml before writing code |
| operationId | Links HTTP endpoints to ARO feature sets |
| Application-Start | Required entry point; exactly one per application |
| Feature Set | Named block of business logic |
| Action Statements | Verb the <result> for the <object> |
| Action | Role | Example |
|---|---|---|
Extract |
Request | Get data from request/context |
Create |
Own | Create new data |
Compute |
Own | Calculate/transform data |
Validate |
Own | Check data validity |
Store |
Export | Save to repository |
Return |
Response | Send response |
Log |
Export | Write to console/log |
Start |
Export | Start a service |
Stop |
Export | Stop a service |
-
Add more endpoints: Define new paths in
openapi.yamlwith uniqueoperationIdvalues, then create matching feature sets -
Accept parameters: Use path parameters (
/users/{id}) and access them viaExtract the <id> from the <pathParameters: id> -
Handle request bodies: For POST/PUT endpoints, use
Extract the <data> from the <request: body> -
Add validation: Use
Validateactions to check input data -
Connect to storage: Use
StoreandRetrievewith repositories
Make sure your application directory contains an openapi.yaml file. Without it, the HTTP server won't start.
Your operationId values don't match any feature set names. Ensure each operationId in your contract has a matching feature set.
Check that the port (8000) is not already in use by another application.
The complete Hello World API example is available at:
Examples/HelloWorldAPI/
├── openapi.yaml
├── main.aro
└── hello.aro
Run it with:
aro run ./Examples/HelloWorldAPIFundamentals
- The Basics
- Feature Sets
- Actions
- Variables
- Type System
- Control Flow
- Error Handling
- Computations
- Dates
- Concurrency
Runtime & Events
I/O & Communication
Advanced