Skip to main content
Actions are the functions of a SLang backend. They accept typed parameters, run backend logic, read and modify data, call modules, and return typed values.

Action Shape

An action has a name, typed parameters, a return type, optional metadata, and either a body or an external implementation.

Reading Data

Use single when the action needs one record. In HTTP contexts, a missing record is surfaced as a not-found response.
Use pageOf when the action returns a collection. A page exposes items, total, and offset. Iterate over page.items, not over the page object itself. where filters support a limited comparison shape. The left side must be a model field or @id. The right side must be an in-scope value, such as an action parameter or local variable, an internal value such as @subject, or a plain string literal.
Add order by <field> when callers need a stable, user-defined ordering. Ordering supports one persisted scalar field or @id; asc is the default direction, and desc reverses it.

Building Nested Response Bodies

When an endpoint needs to return a parent object with related records nested inside it, query the parent record first, then query the child records and assign the child page’s items array into the nested schema field.
After creating a page and two links, GET /public/pages/alice returns a nested links array. Because links := links.items returns the queried ProfileLink records directly, each nested link includes the record fields returned by the API, such as id, title, url, position, page, createdAt, and updatedAt.

Writing Data

Use create Entity { ... } to insert a record. Use update record { ... } to patch fields on an existing record. Use delete record to remove one. When you update a variable holding an entity instance, the variable is rebound to the updated instance, so returning the same variable returns the latest fields.

Strings

Use double-quoted strings for text. For dynamic text, prefer template string interpolation with ${...} inside the string:
Interpolations can include values that resolve to TEXT, NUMBER, or BOOLEAN. For entities, files, pages, and other structured values, interpolate a specific scalar field such as ${task.title} rather than the whole value. The + operator can concatenate two text-compatible operands, such as TEXT, EMAIL, PHONE_NUMBER, ADDRESS, or URL, and can include NUMBER or BOOLEAN on the other side. Keep each + expression binary. Do not write long chains such as "Task: " + task.title + ", categories: " + categoryNames; use a template string, split the expression into steps, or parenthesize each binary pair.

Control Flow

SLang supports:
  • if / else
  • for item in array
  • while
  • break and continue
  • boolean logic with and, or, and not
  • arithmetic and comparisons for compatible primitive values
Use assert(description := "...", rule := condition) when an action should fail unless an invariant is true.