4 Application Backend
| (require rivet) | package: rivet |
4.1 RPCs, Events, State, Records, and Enums
State descriptors and the registry records behind RPCs, Events, Records, and Enums are intentionally opaque. Applications declare them with the forms in this section; code generators consume the immutable backend-schema snapshot instead of depending on mutable runtime representation.
The type names in declarations are schema grammar, not Racket variables or runtime descriptor values. They are interpreted only inside the declaration forms below. This keeps application code honest: use ordinary Racket predicates and contracts for runtime values, and use the generated Keel schema when a tool needs to inspect the application contract.
syntax
(define-rpc (name [arg : type] ... : result-type) body ...)
syntax
(define-record name ([field : field-type] ...))
syntax
(define-enum name (case ...))
syntax
(define-event name : type)
syntax
(define-state name : type initial-value)
procedure
(state-set! state value) → void?
state : state? value : any/c
(require rivet) (define-rpc (greet [name : String] : String) (string-append "Hello, " name)) (define-event notification : String) (define-state signed-in? : Bool #f)
4.2 Keel Schema Projection
| (require rivet/keel) | package: rivet |
Keel is the transport-neutral application contract shared by Rivet and Glaze. These adapters expose the same application model without moving RVT1 framing, native client generation, embedding, or UI ownership out of Rivet.
procedure
(backend-schema->app-schema schema #:id id [ #:revision revision]) → any/c schema : hash? id : string? revision : exact-nonnegative-integer? = 1
procedure
(current-backend-app-schema #:id id [ #:revision revision]) → any/c id : string? revision : exact-nonnegative-integer? = 1
4.3 Serving an Embedded Connection
procedure
(serve in out [ #:max-pending-requests max-pending-requests #:max-outgoing-frames max-outgoing-frames]) → void? in : input-port? out : output-port? max-pending-requests : exact-positive-integer? = 1024 max-outgoing-frames : exact-positive-integer? = 64
procedure
(serve-fds input-fd output-fd [ #:max-pending-requests max-pending-requests #:max-outgoing-frames max-outgoing-frames]) → void? input-fd : exact-integer? output-fd : exact-integer? max-pending-requests : exact-positive-integer? = 1024 max-outgoing-frames : exact-positive-integer? = 64
parameter
(current-rivet-diagnostic-sink sink) → void? sink : procedure?
procedure
(backend-schema) → hash?
procedure
(rpc-schema) → list?
procedure
(event-schema) → list?
procedure
(state-schema) → list?
procedure
(record-schema) → list?
procedure
(enum-schema) → list?
4.4 RVT1 Framing and the Value Codec
| (require rivet/protocol) | package: rivet |
Applications normally reach the wire through serve and generated clients. This module is the framing layer underneath: it is public because debuggers, protocol fuzzers, and alternative transports consume exactly the same bytes, and because the transport limits are the contract between an application backend and its host.
Every frame carries the RVT1 magic, the protocol version, a message type, an unsigned 64-bit identifier, and a payload. Payloads use a small tagged value codec that covers the RVT1 value grammar; framing and the value codec are independent so later grammar revisions cannot change transport semantics.
struct
type : exact-integer? id : exact-nonnegative-integer? payload : bytes?
procedure
(write-frame f [out]) → void?
f : frame? out : output-port? = (current-output-port)
procedure
(read-frame [in]) → (or/c frame? eof-object?)
in : input-port? = (current-input-port)
procedure
(encode-value value) → bytes?
value : any/c
procedure
(decode-value payload) → any/c
payload : bytes?
value
value
max-frame-payload-size : exact-nonnegative-integer? = 67108864
value
value
max-value-nodes : exact-positive-integer? = 262144
value
value
value
value
value
value
value
4.5 Application Resources
| (require rivet/resources) | package: rivet |
Locates the read-only application resource directory staged by the build. The same API answers for development layouts, installed .app bundles, MSI installs, and Linux prefix layouts, so backends never hardcode platform resource paths.
parameter
(current-resource-root) → (or/c #f path-string?)
(current-resource-root root) → void? root : (or/c #f path-string?)
procedure
(resource-root) → path?
procedure
(resource-path piece ...) → path?
piece : path-string?