Click here to sign up to SurrealDB Cloud

Back to top
Documentation Integrations SDKs Rust

Rust icon Rust SDK for SurrealDB

The SurrealDB SDK for Rust enables simple and advanced querying of a remote or embedded database from a browser or from server-side code. Remote connections automatically reconnect when the connection is terminated.

To contribute to this documentation, edit this file on GitHub.

To contribute to the SDK code, submit an Issue or Pull Request here.

This SDK is compatible with V1.0.0

Install the SDK

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

cargo add surrealdb

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.

use serde::{Deserialize, Serialize};
use surrealdb::engine::remote::ws::Ws;
use surrealdb::opt::auth::Root;
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<()> {
    // Connect to the server
    let db = Surreal::new::<Ws>("127.0.0.1:8000").await?;

    // Signin as a namespace, database, or root user
    db.signin(Root {
        username: "root",
        password: "root",
    })
    .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(())
}

To run the example above, you will need to add the following additional dependencies:

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

Then make sure your SurrealDB server is running on 127.0.0.1:8000 and run your app from the command line with:

cargo run

SDK methods

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

Function Description
Surreal::init() static 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

Surreal::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.

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(())
}

db.connect(endpoint)

Connects to a local or remote database endpoint.

Arguments Description
endpoint Required The database endpoint to connect to.
// 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?;

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

Connects to a local or remote database endpoint.

Arguments Description
endpoint Required The database endpoint to connect to.
let db = Surreal::new::<Ws>("127.0.0.1:8000").await?;

db.use_ns(ns).use_db(db)

Switch to a specific namespace and database.

Arguments Description
ns Required Switches to a specific namespace.
db Required Switches to a specific database.
db.use_ns("test").use_db("test").await?;

db.signup(credentials)

Signs up to a specific authentication scope.

Arguments Description
credentials Required Variables used in a signup query.
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();

db.signin(credentials)

Signs in to a specific authentication scope.

Arguments Description
credentials Required Variables used in a signin query.
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();

db.invalidate()

Invalidates the authentication for the current connection.

db.invalidate().await?;

db.authenticate(token)

Authenticates the current connection with a JWT token.

Arguments Description
token Required The JWT authentication token.
db.authenticate(jwt).await?;

db.set(key, val)

Assigns a value as a parameter for this connection.

Arguments Description
key Required Specifies the name of the variable.
val Required Assigns the value to the variable name.
// 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?;

db.query(sql).bind(vars)

Runs a set of SurrealQL statements against the database.

Arguments Description
sql Required Specifies the SurrealQL statements.
vars Optional Assigns variables which can be used in the query.
// 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)?;

db.select(resource)

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

Arguments Description
resource Required The table name or a record ID to select.
// 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?;

This function will run the following query in the database:

SELECT * FROM $resource;

db.create(resource).content(data)

Creates a record in the database.

Arguments Description
resource Required The table name or the specific record ID to create.
data Optional The document / record data to insert.
// 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?;

This function will run the following query in the database:

CREATE $resource CONTENT $data;

db.update(resource).content(data)

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

This function replaces the current document / record data with the specified data.
Arguments Description
resource Required The table name or the specific record ID to update.
data Optional The document / record data to insert.
// 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?;

This function will run the following query in the database:

UPDATE $resource CONTENT $data;

db.update(resource).merge(data)

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

This function merges the current document / record data with the specified data.
Arguments Description
resource Required The table name or the specific record ID to change
data Optional The document / record data to insert.
// 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?;

This function will run the following query in the database:

UPDATE $resource MERGE $data;

db.update(resource).patch(data)

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

This function patches the current document / record data with the specified JSON Patch data.
Arguments Description
resource Required The table name or the specific record ID to modify.
data Optional The JSON Patch data with which to modify the records.
// 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?;

This function will run the following query in the database:

UPDATE $resource PATCH $data;

db.delete(resource)

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

Arguments Description
resource Required The table name or a record ID to select.
// 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?;

This function will run the following query in the database:

DELETE FROM $resource RETURN BEFORE;