OxL Reference

Services and rpc

A service declares a contract, a set of rpc methods; impl implements it. The call Users.get(1) does not know where the implementation lives: in this process or on another node of the cluster. The result of a call always includes NetError (§6.5): the network may fail even when the call is currently in process. Access to methods is closed by default: @public opens a method to the outside, @internal is for calls between services (§13.4).

oxl✓ checked in CI
@error data NotFound { what: str }

service Users {
  @public rpc get(id: u64) -> str | NotFound
  @public rpc count() -> i32
}

impl Users {
  rpc get(id) {
    if id == 1 { "ann" } else { fail NotFound{ what: "user {id}" } }
  }
  rpc count() { 2 }
}

fn show(r: str | NotFound | NetError) io {
  match r {
    str s => print("ok {s}")
    NotFound e => print("not found: {e.what}")
    NetError e => print("net error")
  }
}

fn main() io, net {
  show(Users.get(1))
  show(Users.get(7))
  match Users.count() {
    i32 n => print("{n} users")
    NetError e => print("net error")
  }
}
Output
ok ann
not found: user 7
2 users

rpc attributes#

The behaviour of a method is set by attributes next to the contract: @timeout(5s) (default deadline), @idempotent (a repeat with the same key returns the stored response), @readonly, @retry(n, backoff: b) (only together with @idempotent or @readonly), @public / @internal / @allow(...); the caller's deadline is passed on along the chain of calls (§10.2, §8.6). Inside a handler the context ctx is available: the caller (ctx.caller), the deadline, traceId, meta.

oxl✓ checked in CI
service Info {
  @timeout(5s)
  @public rpc whoami() -> str
}

impl Info {
  rpc whoami() {
    let anon = ctx.caller is .Anonymous
    let live = ctx.deadline > now() && ctx.deadline <= now() + 5s
    "anonymous={anon} deadline-ok={live}"
  }
}

fn main() io, net, time {
  match Info.whoami() {
    str s => print(s)
    NetError e => print("net error")
  }
}
Output
anonymous=true deadline-ok=true

A client to an external address#

Users.connect("host:port", tls: ClientTls{}) returns a Client<Users>: the same methods, but to a concrete address (for example to a service outside the cluster). gRPC services are imported with import proto (§16.3), and clients in other languages are generated by oxl gen. Contracts are checked for compatibility against the file oxl.schema.lock (§9.2, III.2): a breaking schema change is a compile error (schema-break).

See also

OxL 1.0.0-beta · Documentation version 1.0.0-beta© OxwaldLink · generated from the Standard, the std sources and the guides