Skip to content

State

A state block declares server-global fields that persist across requests — enough to build a working in-memory CRUD API.

weld
type NewUser = { name: string, email: string? }
type User = { id: int, name: string, email: string? }

state db {
    var users: [User] = []
    var nextId: int = 1
}

route POST "/users" (body input: NewUser) -> User {
    let user = User { id: db.nextId, name: input.name, email: input.email }
    db.users = push(db.users, user)
    db.nextId = db.nextId + 1
    status 201
    respond user
}

route GET "/users" -> [User] { respond db.users }

How it persists

Values stored into state are deep-copied into a persistent allocator, so request-scoped strings survive after the request completes. Access it by the block name (db.users, db.nextId).

Concurrency

In the default thread-per-connection server, state is guarded by an Io.RwLock — shared reads, exclusive writes. A map in state is lock-guarded too, so a counter keyed by page or client IP is safe under concurrency:

weld
state counts { var hits: [string: int] = [:] }

route GET "/hit/:page" (page: string) {
    let n = (counts.hits[page] ?? 0) + 1
    counts.hits[page] = n
    respond "{n}"
}

State is the foundation for features written in Weld itself — for example, rate limiting is a [string: Bucket] map in state, keyed by client IP.