BUILD BACKENDS

Standard library

Builtin signatures, typed collections and storage operation results.

Signatures below describe checked types. Builtins are reserved names. Argument count/type failures occur at compile time. Runtime conversion failures unwind; HTTP handlers return 500 unless the failure is explicitly a client-body error.

Pure functions

Function Return Behavior
json(value) Json Encode a serializable primitive, struct, enum or supported container
println(value) void Print serializable values and newline; app output goes to stderr
assert(condition: bool) void Unwind if false; language tests report failure
len(value: String) i64 Unicode scalar count, not bytes or graphemes
len(value: Json) i64 Array/object length or JSON string scalar count; other kinds fail
json_get(value: Json, key: String) Json Object field; missing/wrong container returns null
json_at(value: Json, index: i64) Json Zero-based array value; invalid index/container returns null
json_kind(value: Json) String null, number, bool, string, array, or object
as_string(value: Json) String Checked string conversion
as_i64(value: Json) i64 Checked integer conversion within i64 range
as_bool(value: Json) bool Checked boolean conversion
json_parse(value: String) Json Parse valid JSON; invalid JSON fails
secure_eq(a: String, b: String) bool Constant-time content comparison using subtle; differing lengths may be distinguished
response(status: i64, body: Json) Response JSON response; status must be 200..599
text_response(status: i64, body: String) Response Text response; same status bounds

JSON strings escape control characters correctly. Parsed numbers preserve their JSON numeric spelling with the backend’s arbitrary-precision JSON parser; arithmetic in the language still requires i64. Serializable structs support strict codecs. Use response_header for custom headers. Cookie/session authentication is an application responsibility.

Request and environment APIs

These are permitted only inside apps and their private helpers. Each handler has a thread-local request context; it cannot read another request’s context.

Function Return Behavior
request_text() String Entire bounded body; invalid UTF-8 gives 400
request_json() Json Parse body as JSON; invalid JSON gives 400
header(name: String) String Case-insensitive header lookup; absent/non-text value gives empty string
param(name: String) String Decoded route parameter; absent gives empty string
query(name: String) String Form-decoded query value; last duplicate wins; absent gives empty string
env("LITERAL_NAME") String Read a declared environment capability

request_json parses the body independently of Content-Type; application code can inspect header("content-type") if it needs to reject another media type. Startup refuses missing or empty declared environment variables. The compiler requires a literal name and matching permit env. It does not embed secret values into the binary. RYFT_WORKER_* names are reserved for supervisor IPC and cannot be declared as language capabilities. Do not log authorization headers or environment values.

SQLite APIs

storage db: sqlite("catalog.db");
let written = db_exec(db, "INSERT INTO products (name) VALUES (?1)", [name]);
let found = db_query(db, "SELECT id, name FROM products WHERE id = ?1", [id]);

db_exec(handle, sql: String, params: Json) -> Json executes one statement. Success: {"ok":true,"affected":N,"last_insert_id":N}.

db_query(handle, sql: String, params: Json) -> Json executes a read-only statement. Success: {"ok":true,"rows":[{"column":value}]}. Give result columns unique names, using aliases when joining tables.

Both return {"ok":false,"error":"..."} on database/parameter errors. SQL must be a source string literal; dynamic SQL strings are rejected during compilation. Choose among literal templates in branches and bind data values. Check ok before reading result fields; do not expose internal database error details from public endpoints. The first argument is an app-local declared handle, not an arbitrary filename or value.

Parameters must be a JSON array of scalar values: null, i64, bool (stored as 0/1), String, or finite numeric JSON. Integer spellings must fit i64; decimal and exponent spellings convert to finite SQLite REAL. Nonfinite parameters or query results return an error. Bind values with ?1 placeholders; never concatenate request input into SQL. Identifiers and SQL syntax cannot be bound as parameters. Floating point database values have SQLite/IEEE precision, not arbitrary-precision arithmetic.

Databases open at server startup inside separate app directories, use WAL and foreign keys, and have a five-second SQLite busy timeout. A per-database mutex serializes access; other databases/apps can progress independently. Statements check the handler deadline through a SQLite progress callback. ATTACH, DETACH, application PRAGMAs, unknown authorization actions, and extension loading are denied. Multi-statement execution and BLOB result decoding are unsupported. Queries are capped at 10,000 rows and 16 MiB of encoded row data. Paginate.

Explicit transaction/savepoint statements are rejected to prevent requests from sharing an open transaction on the same connection. Use db_transaction for a bounded, atomic batch of literal SQL templates. Connection pools and general schema migration tracking, PostgreSQL, Redis and ORM features are not implemented. Each normal statement uses SQLite’s statement-level atomicity; separate API calls are not one transaction. Protect the data directory with OS permissions and back it up using SQLite-aware procedures.

Strings and parsing

Function Return Behavior
trim(value: String) String Remove surrounding Unicode whitespace
lowercase(value: String) / uppercase(value: String) String Unicode case conversion
contains(value: String, needle: String) bool Literal substring check
starts_with(value: String, prefix: String) / ends_with(value: String, suffix: String) bool Literal boundary checks
split(value: String, separator: String) List Split into owned strings
is_hex(value: String) / is_digits(value: String) bool Nonempty ASCII hex/decimal spelling checks
regex_escape(value: String) String Escape literal text for regular-expression use
parse_i64(value: String) Result<i64,String> Fallible signed integer parsing
parse_json(value: String) Result<Json,String> Fallible JSON parsing
to_string(value: i64) String Decimal integer spelling
now_millis() i64 Unix epoch milliseconds
uuid() String OS-random UUID v4; app-only

Typed collections and codecs

Function Return Behavior
list(values...) List Nonempty homogeneous typed list
list_push(values: List<T>, value: T) List Return an extended list
list_at(values: List<T>, index: i64) Option Safe zero-based lookup
map_put(values: Map<String,T>, key: String, value: T) Map<String,T> Return an updated map
map_get(values: Map<String,T>, key: String) Option Safe key lookup
len(value: List<T> or Map<String,T>) i64 Element count

List<T>.new() and Map<String,T>.new() create empty containers. Keep the updated value returned by push/put. Serializable values support .to_json() and json(value); supported types expose .from_json(Json) -> Result<T,String>. Struct decoding rejects missing/unknown fields and invalid types. See types and errors.

Request metadata and headers

Function Return Behavior
request_path() String Path without query string
request_method() String Request method
request_id() String Runtime request identifier
response_header(value: Response, name: String, content: String) Response Add a validated header; framing and hop-by-hop headers are rejected

Request APIs require a request context and cannot be used in startup/shutdown hooks or pure global helpers. RYFT_CONTROL_TOKEN and RYFT_WORKER_* names are reserved for the runtime.

SQLite transaction batches

db_transaction(handle, steps: Json) -> Json accepts 1..100 source-literal objects with literal sql and a params value. Success returns {"ok":true,"results":[{"affected":1,"last_insert_id":1}]}. A failed step rolls back and returns ok: false. User SQL cannot issue its own transaction controls. See HTTP and storage for an executable example.

MongoDB APIs

Declare storage db: mongodb("MONGODB_URI", "database"); and permit env "MONGODB_URI"; in an app. Supply the URI at runtime. The first argument below must be the app-local handle; collection arguments must be source literals. All functions return Json.

Function Success envelope fields besides ok
mongo_ping(handle) ok: true
mongo_find(handle, collection: String, filter: Json, limit: i64, skip: i64, sort: Json) rows array
mongo_insert(handle, collection: String, document: Json) inserted_id
mongo_update(handle, collection: String, filter: Json, update: Json) matched, modified
mongo_delete(handle, collection: String, filter: Json) deleted count
mongo_index(handle, collection: String, keys: Json, unique: bool) ok: true
mongo_drop(handle, collection: String) ok: true; deletes the entire collection
mongo_transaction(handle, steps: Json) results array

Errors return {"ok":false,"error":"..."} with redacted driver messages. Find limit is 1..1000, skip is 0..100000, and encoded rows are limited to 16 MiB. Update supports $set, $inc and $unset; executable filter operators are blocked. Update and delete each affect one matching document. ObjectIds encode as strings, with Extended JSON $oid available in filters.

Transactions use literal collection and operation (insert, update or delete) plus document or filter/update. A failed operation aborts the batch. Unknown commit outcomes can return uncertain: true after bounded commit retries; reconcile before replaying writes. Compatible deployment topology and permissions are required. HTTP deadlines do not forcibly cancel synchronous driver operations.

Ryft 0.3.0Source: docs/stdlib.md

Search installation, types, routes, storage and more.