View Routes
View routes are read-only entry points. They can inspect entity state but cannot modify it, send messages, or perform side effects. Use them to expose queries to callers and other entities.
Syntax
View routes are declared with the view keyword and must specify a return type:
view get_balance() -> U256 => [
return(m_balance)
]
Return Type
Every view route must declare a return type with -> Type and include a
return(value) action:
view get_owner() -> address => [
return(m_owner)
]
view get_name() -> String => [
return(m_name)
]
view total_supply() -> U256 => [
return(m_total_supply)
]
Read-Only Guarantee
View routes have the following restrictions:
| Allowed | Forbidden |
|---|---|
| Read member values | Modify members (no transforms) |
| Call pure functions | Send messages (~>) |
Use if/else, match | Deploy entities |
| Compute intermediate values | Side effects (~>, deploy, emit, evm::) |
These constraints are enforced by the compiler. A view route that attempts to trigger a member transform or send a message will produce a compilation error.
Computed Views
View routes can perform computations on state before returning:
view get_balance_of(account: address) -> U256 => [
return(m_balances.get(account).unwrap_or(0))
]
view is_approved(owner: address, spender: address) -> bool => [
let allowance = m_allowances.get(owner)
.unwrap_or({})
.get(spender)
.unwrap_or(0);
return(allowance > 0)
]
Conditional Returns
Views can use if/else and match to determine the return value:
view get_status_label() -> String => [
return(match m_status {
Status::Active => "active",
Status::Paused => "paused",
Status::Closed => "closed",
_ => "unknown"
})
]
Views with Parameters
View routes can accept parameters to query specific data:
view get_listing(id: u64) -> Listing => [
return(m_listings[id])
]
view get_vote_count(proposal_id: u64) -> u64 => [
return(m_votes.get(proposal_id).unwrap_or(0))
]
No Member Transforms
View routes do not appear in member transform blocks. Since views cannot
modify state, no member declares in get_balance(_) => .... If you find
yourself writing a member transform for a view route, you need a regular route
instead.
Complete Example
An entity with multiple view routes:
entity Token {
routes {
// ... regular routes ...
view name() -> String => [
return(m_name)
]
view symbol() -> String => [
return(m_symbol)
]
view total_supply() -> U256 => [
return(m_total_supply)
]
view balance_of(account: address) -> U256 => [
return(m_balances.get(account).unwrap_or(0))
]
view allowance(owner: address, spender: address) -> U256 => [
return(
m_allowances.get(owner)
.unwrap_or({})
.get(spender)
.unwrap_or(0)
)
]
}
}