Skip to main content
Version: 1.2.x

Embedding in Rust

Embedding in Rust

SurrealDB is designed to be run in many different ways, and environments. Due to the separation of the storage and API layers, SurrealDB can be run in embedded mode, from within a number of different language environments. In Rust, SurrealDB can be run as an in-memory database, it can persist data using a file-based storage engine, or on a distributed cluster.

Install the SDK

First, create a new project using cargo new and add the SurrealDB crate to your dependencies:

cargo add surrealdb

You will then need to enable the appropriate features (for a full list see https://crates.io/crates/surrealdb):

# For an in memory database
cargo add surrealdb --features kv-mem

# For a RocksDB file
cargo add surrealdb --features kv-rocksdb

# For a SpeeDB file
cargo add surrealdb --features kv-speedb

# For FoundationDB cluster (FoundationDB must be installed and the appropriate version selected)
cargo add surrealdb --features kv-fdb-7_1

# For a TiKV cluster (TiKV and other dependencies must be installed)
cargo add surrealdb --features kv-tikv

You will need to add the following additional dependencies:

cargo add serde --features derive
cargo add tokio --features macros,rt-multi-thread

Connect to SurrealDB

Open src/main.rs and replace everything in there with the following code to try out some basic operations using the SurrealDB SDK with an embedded database. Look at integrations to connect to a database.

use serde::{Deserialize, Serialize};
use surrealdb::engine::local::Mem;
use surrealdb::sql::Thing;
use surrealdb::Surreal;

#[derive(Debug, Serialize)]
struct Name<'a> {
first: &'a str,
last: &'a str,
}

#[derive(Debug, Serialize)]
struct Person<'a> {
title: &'a str,
name: Name<'a>,
marketing: bool,
}

#[derive(Debug, Serialize)]
struct Responsibility {
marketing: bool,
}

#[derive(Debug, Deserialize)]
struct Record {
#[allow(dead_code)]
id: Thing,
}

#[tokio::main]
async fn main() -> surrealdb::Result<()> {
// Create database connection
let db = Surreal::new::<Mem>(()).await?;

// Select a specific namespace / database
db.use_ns("test").use_db("test").await?;

// Create a new person with a random id
let created: Vec<Record> = db
.create("person")
.content(Person {
title: "Founder & CEO",
name: Name {
first: "Tobie",
last: "Morgan Hitchcock",
},
marketing: true,
})
.await?;
dbg!(created);

// Update a person record with a specific id
let updated: Option<Record> = db
.update(("person", "jaime"))
.merge(Responsibility { marketing: true })
.await?;
dbg!(updated);

// Select all people records
let people: Vec<Record> = db.select("person").await?;
dbg!(people);

// Perform a custom advanced query
let groups = db
.query("SELECT marketing, count() FROM type::table($table) GROUP BY marketing")
.bind(("table", "person"))
.await?;
dbg!(groups);

Ok(())
}

Run your program from the command line with:

cargo run

SDK methods

The Rust SDK comes with a number of built-in functions.

FunctionDescription
Surreal::init()Initialises a static database engine
db.connect(endpoint)Connects to a specific database endpoint, saving the connection on the static client
Surreal::new::<T>(endpoint)Connects to a local or remote database endpoint
db.use_ns(namespace).use_db(database)Switch to a specific namespace and database
db.signup(credentials)Signs up a user to a specific authentication scope
db.signin(credentials)Signs this connection in to a specific authentication scope
db.invalidate()Invalidates the authentication for the current connection
db.authenticate(token)Authenticates the current connection with a JWT token
db.set(key, val)Assigns a value as a parameter for this connection
db.query(sql)Runs a set of SurrealQL statements against the database
db.select(resource)Selects all records in a table, or a specific record
db.create(resource).content(data)Creates a record in the database
db.update(resource).content(data)Updates all records in a table, or a specific record
db.update(resource).merge(data)Modifies all records in a table, or a specific record
db.update(resource).patch(data)Applies JSON Patch changes to all records in a table, or a specific record
db.delete(resource)Deletes all records, or a specific record

.init()

The DB static singleton ensures that a single database instance is available across very large or complicated applications. With the singleton, only one connection to the database is instantiated, and the database connection does not have to be shared across components or controllers.

Method Syntax
Surreal::init()

Example usage

static DB: Lazy<Surreal<Client>> = Lazy::new(Surreal::init);

#[tokio::main]
async fn main() -> surrealdb::Result<()> {
// Connect to the database
DB.connect::<Wss>("cloud.surrealdb.com").await?;
// Select a namespace + database
DB.use_ns("test").use_db("test").await?;
// Create or update a specific record
let tobie: Option<Record> = DB
.update(("person", "tobie"))
.content(Person { name: "Tobie" })
.await?;
Ok(())
}

.connect()

Connects to a local or remote database endpoint.

Method Syntax
db.connect(endpoint)

Arguments

ArgumentDescription
endpointREQUIREDThe database endpoint to connect to.

Example usage

// Connect to a local endpoint
DB.connect::<Ws>("127.0.0.1:8000").await?;
// Connect to a remote endpoint
DB.connect::<Wss>("cloud.surrealdb.com").await?;

.new()

Connects to a local or remote database endpoint.

Method Syntax
Surreal::new:: <T>(endpoint)

Arguments

ArgumentsDescription
endpointREQUIREDThe database endpoint to connect to.

Example usage

let db = Surreal::new::<Ws>("127.0.0.1:8000").await?;

.use_ns() and .use_db()

Switch to a specific namespace and database.

Method Syntax
db.use_ns(ns).use_db(db)

Arguments

ArgumentsDescription
nsREQUIREDSwitches to a specific namespace.
dbREQUIREDSwitches to a specific database.

Example usage

db.use_ns("test").use_db("test").await?;

.signup()

Signs up to a specific authentication scope.

Method Syntax
db.signup(credentials)

Arguments

ArgumentsDescription
credentialsREQUIREDVariables used in a signup query.

Example usage

use serde::Serialize;
use surrealdb::opt::auth::Scope;

#[derive(Serialize)]
struct Credentials<'a> {
email: &'a str,
pass: &'a str,
}

let jwt = db.signup(Scope {
namespace: "test",
database: "test",
scope: "user",
params: Credentials {
email: "info@surrealdb.com",
pass: "123456",
},
}).await?;

// ⚠️: It is important to note that the token should be handled securely and protected from unauthorized access.
let token = jwt.as_insecure_token();

.signin()

Signs in to a specific authentication scope.

Method Syntax
db.signin(credentials)

Arguments

ArgumentsDescription
credentialsREQUIREDVariables used in a signin query.

Example usage

use serde::Serialize;
use surrealdb::opt::auth::Scope;

#[derive(Serialize)]
struct Credentials<'a> {
email: &'a str,
pass: &'a str,
}

let jwt = db.signin(Scope {
namespace: "test",
database: "test",
scope: "user",
params: Credentials {
email: "info@surrealdb.com",
pass: "123456",
},
}).await?;

// ⚠️: It is important to note that the token should be handled securely and protected from unauthorized access.
let token = jwt.as_insecure_token();

.invalidate()

Invalidates the authentication for the current connection.

Method Syntax
db.invalidate(credentials)

Example usage

db.invalidate().await?;

.authenticate()

Authenticates the current connection with a JWT token.

Method Syntax
db.authenticate(token)

Arguments

ArgumentsDescription
tokenREQUIREDThe JWT authentication token.

Example usage

db.authenticate(jwt).await?;

.set()

Assigns a value as a parameter for this connection.

Method Syntax
db.set(key, val)

Arguments

ArgumentsDescription
keyREQUIREDSpecifies the name of the variable.
valREQUIREDAssigns the value to the variable name.

Example usage

// Assign the variable on the connection
db.set("name", Name {
first: "Tobie",
last: "Morgan Hitchcock",
}).await?;
// Use the variable in a subsequent query
db.query("CREATE person SET name = $name").await?;
// Use the variable in a subsequent query
db.query("SELECT * FROM person WHERE name.first = $name.first").await?;

.query()

Runs a set of SurrealQL statements against the database.

Method Syntax
db.query(sql).bind(vars)

Arguments

ArgumentsDescription
sqlREQUIREDSpecifies the SurrealQL statements.
varsOPTIONALAssigns variables which can be used in the query.

Example usage

// Run some queries
let sql = "
CREATE person;
SELECT * FROM type::table($table);
";
let mut result = db
.query(sql)
.bind(("table", "person"))
.await?;
// Get the first result from the first query
let created: Option<Person> = result.take(0)?;
// Get all of the results from the second query
let people: Vec<Person> = result.take(1)?;

.select()

Selects all records in a table, or a specific record, from the database.

Method Syntax
db.select(resource)

Arguments

ArgumentsDescription
resourceREQUIREDThe table name or a record ID to select.

Example usage

// Select all records from a table
let people: Vec<Person> = db.select("person").await?;
// Select a specific record from a table
let person: Option<Person> = db.select(("person", "h5wxrf2ewk8xjxosxtyc")).await?;

Translated query

This function will run the following query in the database:

SELECT * FROM $resource;

.create()

Creates a record in the database.

Method Syntax
db.create(resource).content(data)

Arguments

ArgumentsDescription
resourceREQUIREDThe table name or the specific record ID to create.
dataOPTIONALThe document / record data to insert.

Example usage

// Create a record with a random ID
let people: Vec<Person> = db.create("person").await?;
// Create a record with a specific ID
let record: Record = db
.create(("person", "tobie"))
.content(Person {
name: "Tobie",
settings: {
active: true,
marketing: true,
},
}).await?;

Translated query

This function will run the following query in the database:

CREATE $resource CONTENT $data;

.update().content()

Updates all records in a table, or a specific record, in the database.

Method Syntax
db.update(resource).content(data)
NOTE: This function replaces the current document / record data with the specified data.

Arguments

ArgumentsDescription
resourceREQUIREDThe table name or the specific record ID to create.
dataOPTIONALThe document / record data to insert.

Example usage

// Update all records in a table
let people: Vec<Person> = db.update("person").await?;
// Update a record with a specific ID
let person: Option<Person> = db
.update(("person", "tobie"))
.content(Person {
name: "Tobie",
settings: {
active: true,
marketing: true,
},
}).await?;

Translated query

This function will run the following query in the database:

UPDATE $resource CONTENT $data;

.update().merge()

Modifies all records in a table, or a specific record, in the database.

Method Syntax
db.update(resource).merge(data)
NOTE: This function merges the current document / record data with the specified data.

Arguments

ArgumentsDescription
resourceREQUIREDThe table name or the specific record ID to create.
dataOPTIONALThe document / record data to insert.

Example usage

// Update all records in a table
let people: Vec<Person> = db.update("person")
.merge(Document {
updated_at: Datetime::default(),
})
.await?;
// Update a record with a specific ID
let person: Option<Person> = db.update(("person", "tobie"))
.merge(Document {
updated_at: Datetime::default(),
settings: Settings {
active: true,
},
})
.await?;

Translated query

This function will run the following query in the database:

UPDATE $resource MERGE $data;

.update().patch()

Applies JSON Patch changes to all records, or a specific record, in the database.

Method Syntax
db.update(resource).patch(data)
NOTE: This function patches the current document / record data with the specified JSON Patch data.

Arguments

ArgumentsDescription
resourceREQUIREDThe table name or the specific record ID to modify.
dataOPTIONALThe JSON Patch data with which to modify the records.

Example usage

// Update all records in a table
let people: Vec<Person> = db.update("person")
.patch(PatchOp::replace("/created_at", Datetime::default()))
.await?;

// Update a record with a specific ID
let person: Option<Person> = db.update(("person", "tobie"))
.patch(PatchOp::replace("/settings/active", false))
.patch(PatchOp::add("/tags", &["developer", "engineer"]))
.patch(PatchOp::remove("/temp"))
.await?;

Translated query

This function will run the following query in the database:

UPDATE $resource PATCH $data;

.delete()

Deletes all records in a table, or a specific record, from the database.

Method Syntax
db.delete(resource)

Arguments

ArgumentsDescription
resourceREQUIREDThe table name or a record ID to select.

Example usage

// Delete all records from a table
let people: Vec<Person> = db.delete("person").await?;
// Delete a specific record from a table
let person: Option<Person> = db.delete(("person", "h5wxrf2ewk8xjxosxtyc")).await?;

Translated query

This function will run the following query in the database:

DELETE FROM $resource RETURN BEFORE;