Expand description
§Supabase Rust Client
A comprehensive Rust client library for Supabase that provides full-featured access to all Supabase services with excellent cross-platform support.
§Features
- 🔐 Authentication: Sign up, sign in, JWT handling, session management
- 🗄️ Database: Full REST API access with query builder, CRUD operations, RPC
- 📁 Storage: File upload, download, management with bucket operations
- ⚡ Realtime: WebSocket subscriptions for live database changes
- 🌍 Cross-platform: Works on native (tokio) and WASM (browser) targets
- 🛡️ Type-safe: Full type safety with serde integration
- ⚙️ Configurable: Feature flags for minimal builds
§Quick Start
Add to your Cargo.toml
:
[dependencies]
supabase-lib-rs = "0.2.0"
tokio = { version = "1.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
§Basic Usage
use supabase::Client;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Post {
id: Option<i32>,
title: String,
content: String,
author_id: i32,
created_at: Option<String>,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize the client
let client = Client::new("your-project-url", "your-anon-key")?;
// Authentication
let auth_response = client.auth()
.sign_in_with_email_and_password("user@example.com", "password")
.await?;
println!("Signed in: {:?}", auth_response.user);
// Database operations
let posts: Vec<Post> = client.database()
.from("posts")
.select("*")
.eq("author_id", "123")
.order("created_at", supabase::types::OrderDirection::Descending)
.limit(10)
.execute()
.await?;
println!("Found {} posts", posts.len());
// Insert new post
let new_post = Post {
id: None,
title: "My First Post".to_string(),
content: "Hello, Supabase!".to_string(),
author_id: 123,
created_at: None,
};
let created: Vec<Post> = client.database()
.insert("posts")
.values(new_post)?
.returning("*")
.execute()
.await?;
println!("Created post: {:?}", created.first());
Ok(())
}
§Feature Flags
Enable only the features you need to reduce bundle size:
[dependencies]
supabase-lib-rs = { version = "0.2.0", features = ["auth", "database"] }
Available features:
auth
- Authentication and user managementdatabase
- Database operations and query builderstorage
- File storage operationsrealtime
- WebSocket subscriptionsnative
- Native tokio runtime (default)wasm
- WebAssembly support for browsers
§Platform Support
§Native Applications
For desktop, server, and mobile applications using tokio:
use supabase::Client;
let client = Client::new("your-url", "your-key")?;
// Full feature support including realtime
let realtime = client.realtime();
realtime.connect().await?;
let subscription = realtime
.channel("posts")
.table("posts")
.subscribe(|msg| println!("Update: {:?}", msg))
.await?;
§WASM/Browser Applications
For web applications running in browsers:
[dependencies]
supabase-lib-rs = { version = "0.2.0", features = ["wasm", "auth", "database", "storage"] }
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
use supabase::Client;
use wasm_bindgen::prelude::*;
// In your WASM entry point:
let client = Client::new("your-url", "your-key").unwrap();
wasm_bindgen_futures::spawn_local(async move {
// Auth works in browser
match client.auth().sign_in_with_email_and_password("user@example.com", "password").await {
Ok(_response) => web_sys::console::log_1(&"Signed in!".into()),
Err(e) => web_sys::console::log_1(&format!("Error: {}", e).into()),
}
});
§Advanced Examples
§Database Query Builder
Build complex queries with the fluent API:
use supabase::{Client, types::OrderDirection};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
struct User {
id: i32,
email: String,
name: Option<String>,
active: bool,
}
let client = Client::new("your-url", "your-key")?;
// Complex query with filters, ordering, and pagination
let active_users: Vec<User> = client.database()
.from("users")
.select("id, email, name, active")
.eq("active", "true")
.ilike("email", "%@company.com")
.order("name", OrderDirection::Ascending)
.limit(50) // Limit to 50 results
.execute()
.await?;
// Update with conditions - using a struct for updates
use std::collections::HashMap;
let mut update_data = HashMap::new();
update_data.insert("last_seen", "now()");
let _updated: Vec<User> = client.database()
.update("users")
.set(update_data)?
.eq("id", "123")
.execute()
.await?;
// Delete with conditions
let _deleted: Vec<User> = client.database()
.delete("users")
.eq("active", "false")
.execute()
.await?;
§File Storage Operations
use supabase::Client;
let client = Client::new("your-url", "your-key")?;
let storage = client.storage();
// Create a bucket
storage.create_bucket("avatars", "avatars", true).await?; // public bucket
// Upload a file
let file_content = b"Hello, world!";
let upload_response = storage
.upload("avatars", "user123/avatar.jpg", file_content.to_vec().into(), None)
.await?;
println!("Uploaded: {}", upload_response.key);
// Download a file
let file_data = storage
.download("avatars", "user123/avatar.jpg")
.await?;
// Get public URL
let public_url = storage.get_public_url("avatars", "user123/avatar.jpg");
println!("Public URL: {}", public_url);
§Realtime Subscriptions
Listen to database changes in real-time:
use supabase::Client;
use supabase::realtime::RealtimeEvent;
let client = Client::new("your-url", "your-key")?;
let realtime = client.realtime();
// Connect to realtime
realtime.connect().await?;
// Subscribe to all changes on a table
let sub1 = realtime
.channel("all-posts")
.table("posts")
.subscribe(|message| {
println!("Posts table changed: {:?}", message.event);
if let Some(record) = &message.payload.record {
println!("New data: {}", record);
}
})
.await?;
// Subscribe to specific events with filters
let sub2 = realtime
.channel("user-posts")
.table("posts")
.event(RealtimeEvent::Insert) // Only new posts
.filter("author_id=eq.123") // Only from specific author
.subscribe(|message| {
println!("New post from author 123!");
})
.await?;
// Later, unsubscribe
realtime.unsubscribe(&sub1).await?;
realtime.unsubscribe(&sub2).await?;
realtime.disconnect().await?;
§Error Handling
The library provides comprehensive error types:
use supabase::{Client, Error};
let client = Client::new("your-url", "your-key").unwrap();
match client.auth().sign_in_with_email_and_password("user@example.com", "wrong").await {
Ok(response) => println!("Success: {:?}", response.user),
Err(Error::Auth { message }) => println!("Auth error: {}", message),
Err(Error::Network { message }) => println!("Network error: {}", message),
Err(Error::Http(e)) => println!("HTTP error: {}", e),
Err(e) => println!("Other error: {}", e),
}
§Configuration
Customize the client behavior:
use supabase::{Client, types::*};
let config = SupabaseConfig {
url: "your-url".to_string(),
key: "your-key".to_string(),
http_config: HttpConfig {
timeout: 30, // 30 second timeout
connect_timeout: 5, // 5 second connect timeout
max_redirects: 3, // Maximum 3 redirects
default_headers: std::collections::HashMap::new(),
},
auth_config: AuthConfig {
auto_refresh_token: true, // Auto-refresh JWT tokens
refresh_threshold: 600, // Refresh 10 minutes before expiry
persist_session: true, // Persist session in storage
storage_key: "custom.auth.token".to_string(),
},
database_config: DatabaseConfig {
schema: "public".to_string(),
max_retries: 3,
retry_delay: 1000,
},
storage_config: StorageConfig {
upload_timeout: 300, // 5 minute upload timeout
max_file_size: 100 * 1024 * 1024, // 100MB max file size
default_bucket: Some("uploads".to_string()),
},
service_role_key: None,
};
let client = Client::new_with_config(config).unwrap();
§Migration from JavaScript SDK
This library follows similar patterns to the JavaScript SDK:
JavaScript | Rust |
---|---|
supabase.auth.signInWithEmailAndPassword() | client.auth().sign_in_with_email_and_password() |
supabase.from('table').select() | client.database().from("table").select() |
supabase.storage.from('bucket').upload() | client.storage().upload("bucket", ...) |
supabase.channel().on().subscribe() | client.realtime().channel().subscribe() |
§Examples Repository
Check out the examples directory for complete applications:
basic_usage.rs
- Overview of all featuresauth_example.rs
- Authentication flowsdatabase_example.rs
- Complex database operationsstorage_example.rs
- File managementrealtime_example.rs
- Live subscriptionsdioxus_example.rs
- Full-stack web appwasm_example.rs
- Browser integration
§Contributing
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
§License
This project is licensed under the MIT License - see the LICENSE file for details.
Re-exports§
pub use client::Client;
pub use error::Error;
pub use error::Result;
pub use auth::Auth;
pub use database::Database;
pub use realtime::Realtime;
pub use storage::Storage;
pub use functions::Functions;
Modules§
- auth
- Authentication module for Supabase
- client
- Main Supabase client
- database
- Database module for Supabase REST API
- error
- Error handling for the Supabase client
- functions
- Edge Functions module for Supabase
- prelude
- Commonly used types and traits for convenient importing
- realtime
- Realtime module for Supabase WebSocket subscriptions
- storage
- Storage module for Supabase file operations
- types
- Common types and data structures for Supabase operations