Api Docs

Rust

Rust client: async OpenAPI client for agdb with Reqwest and trait‑based HTTP abstraction

The rust agdb API client is async only and can be used with any HTTP client that would implement the agdb_api::HttpClient trait. The default implementation uses reqwest. The following is the quickstart guide for the agdb client in Rust (connecting to the server). It assumes an agdb_server is running locally. Please refer to the server guide to learn how to run the server.

Looking for... how to run a server? | another language? | embedded db guide?

Usage

Install Rust

Please install the Rust toolchain from the official source.

Create an application

First we initialize an application called agdb_client with cargo:

cargo init agdb_client

Add dependencies

cargo add agdb --features serde,openapi
cargo add agdb_api
cargo add tokio --features  full
cargo add anyhow

Create the client

The client should point to a running agdb_server:

use agdb_api::AgdbApi;
use agdb_api::ReqwestClient;

#[tokio:main]
async fn main() -> anyhow::Result<()> {
    let mut client = AgdbApi::new(ReqwestClient::new(), "localhost:3000");

    Ok(())
}

Create a database user

First we need to log in as default admin user and create our database user and then login as them:

client.user_login("admin", "admin").await?; // The authentication login is stored in
                                            // the client for subsequent API calls.
                                            // Default admin credentials are "admin/admin".
client.admin_user_add("my_user", "password123").await?;
client.user_login("my_user", "password123").await?; // Login as our newly created user.

Create a database

use agdb_api::DbType;

client.db_add("my_user", "my_db", DbType::Mapped).await?; // Memory mapped database called "my_db"
                                                          // will be created under our "my_user".

Run our first queries

To run queries against the database we call db_exec (for read only queries) and db_exec_mut (for queries that also write to the database). In this case we will insert node "users" and 3 user nodes and connect them together.

Note that we can feed the result of a previous query directly to the next one referencing it with an index into the (previous) results starting with semicolon followed by the index, e.g. :0, :1.
// We derive from agdb::DbType
// so we can use the type in the db.
#[derive(Debug, DbType)]
struct User {
    db_id: Option<DbId>, // The db_id member is optional but
                         // it allows querying your user type
                         // from the database.
    username: String
    age: u64,
}

let users = vec![User { db_id: None, username: "Alice".to_string(), age: 40 },
                 User { db_id: None, username: "Bob".to_string(), age: 30 },
                 User { db_id: None, username: "John".to_string(), age: 20 }];

// We can pass users directly as
// query parameter thanks to the
// implementation of the agdb::DbType
// trait via #[derive(DbType)].
let queries: Vec<QueryType> = vec![QueryBuilder::insert().nodes().aliases("users").query().into(),
                                   QueryBuilder::insert().nodes().values(&users).query().into(),
                                   QueryBuilder::insert().edges().from("users").to(":1").query().into(),
                            ];

client.db_exec_mut("my_user", "my_db", &queries).await?;

Run more queries

Run another query searching & selecting the users and converting them back to the native local object and printing the result:

let queries = vec![QueryBuilder::select()
                    .values(User::db_keys()) // Select only relevant properties for the User struct.
                    .ids(
                        QueryBuilder::search()
                            .from("users") // Start the search from the "users" node.
                            .where_()
                            .key("age") // Examine "age" property.
                            .value(LessThan(40.into())) // Include it in the search result if the value
                                                        // is less than 40.
                            .query(),
                    )
                    .query()];

// Runs the query against the db, grabs the first result and converts it to the collection of users.
let users: Vec<User> = client.db_exec("my_user", "my_db", &queries).await?[0].try_into()?;

println!("{:?}", users);

Run the program

cargo run

Full program

https://github.com/agnesoft/agdb/tree/main/examples/server_client_rust