Surreal Client
A SurrealDB client library for Rust speaking native CBOR over WebSocket.
ws://, wss://, and cbor:// URLs all route through the same CBOR engine — ws:// is the canonical scheme, cbor:// is accepted as an alias for backward compatibility.
Features
- CBOR WebSocket engine: Native CBOR wire format. Preserves SurrealDB types (Datetime, Duration, RecordId, Bytes, Decimal) that JSON cannot carry faithfully.
- JSON convenience methods:
create/select/update/merge/patch/delete/queryaccept and returnserde_json::Value, transcoded to/from CBOR on the wire. Usequery_cborwhen fidelity matters. - Immutable Client Design: Thread-safe, cloneable client with unique sessions.
- Builder Pattern Connection: Intuitive connection configuration.
- Debug mode support: Outputs requests/responses for debugging.
- Multiple Authentication Methods: Root, namespace, database, scope, and JWT token auth.
- Query Interface: Execute raw SurrealQL with parameter binding.
- Session Management: Variables and state management per client.
- Relation Support: Create and query record relationships.
- Transaction Support: Execute multi-statement transactions.
Quick Start
Basic Connection
use SurrealConnection;
use json;
async
DSN Connection
let client = dsn?
.connect
.await?;
Multiple Authentication Methods
// Root authentication
let client = new
.url
.auth_root
.connect.await?;
// Namespace authentication
let client = new
.url
.namespace
.auth_namespace
.connect.await?;
// Database authentication
let client = new
.url
.namespace
.database
.auth_database
.connect.await?;
// Scope authentication
let client = new
.url
.auth_scope
.connect.await?;
// JWT token authentication
let client = new
.url
.auth_token
.connect.await?;
CRUD Operations
// Create
let user = client.create.await?;
// Read
let users = client.select.await?;
let alice = client.select.await?;
// Update
let updated = client.update.await?;
// Delete
let deleted = client.delete.await?;
// Insert (bulk)
let products = client.insert.await?;
// Merge
let merged = client.merge.await?;
// Upsert
let upserted = client.upsert.await?;
Query Interface
// Simple query
let results = client.query.await?;
// Parameterized query
let results = client.query.await?;
// Session variables
client.let_var.await?;
let results = client.query.await?;
client.unset.await?;
Relations
// Create relation
let like = client.relate.await?;
// Query relations
let user_likes = client.query.await?;
let post_likes = client.query.await?;
Client Cloning
Each cloned client has its own session state:
let client1 = connection.connect.await?;
let client2 = client1.clone; // Independent session
// Each client can have different session variables
client1.let_var.await?;
client2.let_var.await?;
// Both clients share the same connection but have separate sessions
Pooling
Normally you have one client and one engine. You can clone your client, but the engine remains the same. As a result, some queries may block other queries.
To avoid this, you can use SurrealPool:
// DSN="ws://root:secret@localhost:8000/bakery/v1?param=X"
let pool = dsn.pool;
let db1 = pool.connect.await?;
let db2 = pool.connect.await?;
// Execute both queries simultaniously
try_join!?
Vantage integration
This crate is designed to work with the Vantage query builders:
let db = dsn.connect.await?;
let select = new
.with_source
.with_condition
.with_order_by;
// Second query: SELECT * FROM client WHERE bakery = bakery:hill_valley order by name
// Create delayed query - can be used inside another query
let associated_query = db.defer.await?;
// Execute and get data right away
let data = db.get.await?;
// Also - can be executed directly
let same_data = associated_query.get.await?;
Error Handling
All operations return Result<T, SurrealError> with comprehensive error types:
use SurrealError;
match client.query.await
TODO: Integration with Vantage models and DataSets.