Skip to Content
🚀 KalamDB v0.3.0-alpha2 is out — Learn more
SDK & ClientRust SDK

Rust SDK (kalam-link)

kalam-link is the official Rust client for KalamDB.

Because the crate is not published yet, use it directly from source.

Install from source

[dependencies] kalam-link = { path = "../KalamDB/link" } tokio = { version = "1", features = ["macros", "rt-multi-thread"] } serde_json = "1"

Adjust the path to where your KalamDB/link directory lives relative to your project.

[dependencies] kalam-link = { git = "https://github.com/jamals86/KalamDB.git" } tokio = { version = "1", features = ["macros", "rt-multi-thread"] } serde_json = "1"

If you need a specific branch, tag, or commit:

kalam-link = { git = "https://github.com/jamals86/KalamDB.git", branch = "main" } # or kalam-link = { git = "https://github.com/jamals86/KalamDB.git", rev = "<commit-sha>" }

Quick start

use kalam_link::{AuthProvider, KalamLinkClient}; #[tokio::main] async fn main() -> kalam_link::Result<()> { let client = KalamLinkClient::builder() .base_url("http://localhost:8080") .auth(AuthProvider::basic_auth("root".to_string(), "".to_string())) .build()?; let response = client .execute_query("SELECT 1 AS ok", None, None, None) .await?; println!("status: {}", response.status); Ok(()) }

Authentication patterns

Basic auth

use kalam_link::{AuthProvider, KalamLinkClient}; let client = KalamLinkClient::builder() .base_url("http://localhost:8080") .auth(AuthProvider::basic_auth( "alice".to_string(), "Secret123!".to_string(), )) .build()?;

Login then use JWT

use kalam_link::{AuthProvider, KalamLinkClient}; let unauthenticated = KalamLinkClient::builder() .base_url("http://localhost:8080") .build()?; let login = unauthenticated.login("alice", "Secret123!").await?; let jwt_client = KalamLinkClient::builder() .base_url("http://localhost:8080") .auth(AuthProvider::jwt_token(login.access_token)) .build()?;

Refresh an access token

let refreshed = jwt_client.refresh_access_token("<refresh-token>").await?; println!("new access token: {}", refreshed.access_token);

Queries

Plain SQL

let res = client .execute_query("SELECT * FROM app.messages LIMIT 10", None, None, None) .await?;

Parameterized SQL

let params = vec![serde_json::json!("conv_42"), serde_json::json!(false)]; let res = client .execute_query( "SELECT * FROM app.messages WHERE conversation_id = $1 AND is_deleted = $2", None, Some(params), None, ) .await?;

Namespace-scoped query

let res = client .execute_query("SELECT * FROM messages", None, None, Some("chat")) .await?;

FILE uploads in SQL

Use FILE("name") placeholders in SQL and pass matching files.

use std::fs; let avatar_data = fs::read("./avatar.png")?; let res = client .execute_with_files( "INSERT INTO app.users (name, avatar) VALUES ($1, FILE(\"avatar\"))", vec![("avatar", "avatar.png", avatar_data, Some("image/png"))], Some(vec![serde_json::json!("Alice")]), None, ) .await?;

Realtime subscriptions

Subscriptions require JWT auth in kalam-link.

use futures_util::StreamExt; let mut sub = jwt_client.subscribe("SELECT * FROM app.messages").await?; while let Some(event) = sub.next().await { match event { Ok(change) => println!("change: {:?}", change), Err(err) => eprintln!("subscription error: {}", err), } }

Topic consumers (consume/ack)

use std::time::Duration; let mut consumer = jwt_client .consumer() .group_id("chat-workers") .topic("app.messages") .max_poll_records(100) .poll_timeout(Duration::from_secs(10)) .build()?; let records = consumer.poll().await?; for record in records { println!("offset={} value={:?}", record.offset, record.value); consumer.mark_processed(&record); } let commit = consumer.commit_sync().await?; println!("committed offset={}", commit.acknowledged_offset);

Common pitfalls

  • base_url(...) is required on the builder.
  • subscribe(...) and WebSocket flows require JWT auth (not Basic auth).
  • Keep tokio in your app dependencies for async runtime support.

Next

Last updated on