OxL Справочник OxL
РусскийEnglish

src/users/users.oxl

oxl
use super.model.*
use std.orm { Db }

// Таблица ORM: схема и миграции выводятся из этого объявления
@table("users") @index(.email)
pub(api) data User {
  @pk pub(api) id: UserId             // первичный ключ
  pub(api) name: Name
  pub(api) email: Email
  pub(api) createdAt: Time = now()             // значение по умолчанию вычисляется при создании
}

// Контракт сервиса: из него генерируются сервер, клиенты и .proto
@v(1) pub(api) service Users {
  @readonly rpc get(id: UserId) -> User | NotFound            // readonly: безопасно повторять и кэшировать
  @idempotent rpc register(name: Name, email: Email) -> User | EmailTaken   // повтор с тем же ключом вернёт первый ответ
}

impl Users {
  dep db: Db                          // зависимость, её даёт provide в cluster.oxl

  // Типы параметров берутся из контракта сервиса
  rpc get(id) { db.find(User, id) ?? fail NotFound{ what: "user", id: id.raw } }

  rpc register(name, email) {
    // Запрос компилируется в SQL при сборке
    let taken = from u in db.User where u.email == email take 1
    if !taken.isEmpty() { fail EmailTaken{} }
    let u = User{ id: UserId(cluster.ids.next() as u64), name, email }   // уникальный id
    db.insert(u)
    u
  }
}

// Доступ для внешних вызовов: по умолчанию всё запрещено.
// На этапе 3 политики разбираются, но не применяются (STAGE3_PLAN, решение 1).
policy Users {
  allow get(id) if caller.isUser("{id}") || caller.has(role: .Support)   // свой профиль или поддержка
  allow register if caller is .Anonymous                             // регистрация — без входа
}

Исходник: examples/shop/src/users/users.oxl