Patterns · 3 of 4
Procedure composition
Procedures can call other procedures. Pass parameters as a single object literal. The whole chain runs in one transaction.
Calling another procedure
proc get_balance(account_id) {
let acc = find_one("accounts", {_id: account_id})
if acc == null { abort "not found" }
return acc.balance
}
proc safe_withdraw(account_id, amount) {
let bal = get_balance({account_id: account_id})
if bal < amount { abort "insufficient funds" }
update("accounts", {_id: account_id}, {$inc: {balance: -amount}})
return {ok: true, withdrawn: amount, remaining: bal - amount}
}
Composing reads
proc get_user(id) { return find_one("users", {_id: id}) }
proc get_orders(uid) { return find("orders", {user_id: uid}) }
proc get_addresses(uid) { return find("addresses", {user_id: uid}) }
proc user_profile(id) {
let user = get_user({id: id})
let orders = get_orders({uid: id})
let addresses = get_addresses({uid: id})
return {user: user, orders: orders, addresses: addresses}
}
Composing writes
proc charge(account_id, amount) {
update("accounts", {_id: account_id}, {$inc: {balance: -amount}})
insert("ledger", {account_id: account_id, type: "charge", amount: amount})
return {ok: true}
}
proc credit(account_id, amount) {
update("accounts", {_id: account_id}, {$inc: {balance: amount}})
insert("ledger", {account_id: account_id, type: "credit", amount: amount})
return {ok: true}
}
proc transfer(from, to, amount) {
charge({account_id: from, amount: amount})
credit({account_id: to, amount: amount})
return {ok: true}
}
Composing validation
proc require_active(user_id) {
let u = find_one("users", {_id: user_id})
if u == null { abort "user not found" }
if !u.active { abort "user not active" }
return u
}
proc post_message(user_id, text) {
require_active({user_id: user_id})
insert("messages", {user_id: user_id, text: text})
return {ok: true}
}
proc upload_file(user_id, size) {
require_active({user_id: user_id})
insert("files", {user_id: user_id, size: size})
return {ok: true}
}
Building a service surface
proc account_actions(action, params) {
if action == "create" { return create_account(params) }
if action == "freeze" { return freeze_account(params) }
if action == "unfreeze" { return unfreeze_account(params) }
if action == "close" { return close_account(params) }
abort "unknown action"
}
Note: A called procedure is just inlined — its steps run in the same transaction. There's no separate retry, no commit between calls.