Crate supabase_rs

Source
Expand description

§Supabase SDK for Rust

This is an unofficial Rust SDK for Supabase, since there is no official SDK for Rust yet.

§Features

  • Insert: Add new rows to a table.
  • Insert if unique: Add a new row only if it does not violate a UNIQUE constraint.
  • Update: Modify existing rows in a table based on a unique identifier.
  • Select: Insert a new row into a table if it does not exist, or update it if it does.
  • Select with count: Select rows from a table and count the number of rows that match the filter criteria.
  • Select with filter: Select rows from a table based on a filter criteria.
  • Select with filter and count: Select rows from a table based on a filter criteria and count the number of rows that match the filter criteria.
  • Delete: Delete a row from a table based on a unique identifier.

§Graphql features

§Feature flags

  • storage: Enables the Storage module to interact with Supabase Storage.
  • nightly: Enables the nightly features.
  • rustls: Forces the client into using rustls over OpenSSL.

§Nightly Build

  • nightly: Enables the GraphQL module to interact with Supabase GraphQL API.

Nightly features are not stable and may break at any time without notice, so use with caution.

Nightly WILL send a warning message, to disable the nightly warning message

disable it in your .env as such:

SUPABASE_RS_NO_NIGHTLY_MSG=true

§Cargo.toml

[dependencies]
supabase-rs = "0.3.7"

// With the [storage] feature
supabase-rs = { version = "0.3.7", features = ["storage"] }

§Usage

First make sure you have initialized the Supabase Client Initalizing the SupabaseClient

§Authentication

The Supabase Client is initialized with the Supabase URL and the Supabase Key. Which are environment variables that can be set in a .env file under the following names or any other

SUPABASE_URL=
SUPABASE_KEY=

§Examples

§Initialize the Supabase Client

use supabase_rs::SupabaseClient;

use dotenv::dotenv;
use std::env::var;

async fn initialize_supabase_client() -> SupabaseClient {
   dotenv().ok(); // Load the .env file

   let supabase_client: SupabaseClient = SupabaseClient::new(
       var("SUPABASE_URL").unwrap(),
       var("SUPABASE_KEY").unwrap()
       ).unwrap();

       supabase_client
  }

This will initialize the Supabase Client with the Supabase URL and the Supabase Key, and return the Supabase Client to be passed to other methods.

§Insert

This will insert a new row into the test table with the value value_test in the dog column.

// i know the imports are self explanatory but it makes it easier for beginners:)
use serde_json::json;
use supabase_rs::SupabaseClient;

// always pass an initialized SupabaseClient to the method
let client = SupabaseClient::new(
    "your_supabase_url", "your_supabase_key"
);

async fn insert_example(
   client: SupabaseClient
) -> Result<(), String> {
    let insert_result = client
        .insert(
            "test",
            json!({
                "dog": "value_test"
            }),
       ).await;

§Insert if unique

This will insert a new row into the test table with the value value_test in the dog column if the value is unique. It’s a drop-in replacement for insert without relying on Supabase’s unique constraints on the database.

use serde_json::json;
use supabase_rs::SupabaseClient;

// always pass an initialized SupabaseClient to the method
let client = SupabaseClient::new(
    "your_supabase_url", "your_supabase_key"
);

async fn insert_example(
   client: SupabaseClient
) -> Result<(), String> {
    let insert_result = client
        .insert_if_unique(
            "test",
            json!({
                "dog": "value_test"
            }),
       ).await;

§Update

This will update the row in the test table with the value value_test in the dog column where the id is 1.

use serde_json::json;
use supabase_rs::SupabaseClient;

let client = SupabaseClient::new(
   "your_supabase_url", "your_supabase_key"
);

async fn update_example(
  client: SupabaseClient
) -> Result<(), String> {
   let update_result = client
      .update_with_column_name(
         "table_name", // the table name
         "column_name",    // the column name to filter by
         "id", // the value to filter by (can be any value to use as key)
         json!({
           "dog": "value_test"  // the new value
         }),
     ).await;

§Select

This will return all dog rows where the value is scooby in the animals table

use supabase_rs::SupabaseClient;

// always pass an initialized SupabaseClient to the method
let client = SupabaseClient::new(
   "your_supabase_url", "your_supabase_key"
);

async fn select_scooby(
   supabase_client: SupabaseClient
) -> Result<(), String> {

let data: Result<Vec<Value>, String> = supabase_client
   .select("animals")
   .eq("dog", "scooby")
   .execute()
   .await;

§Select on specific column

This will return all the dog rows where the value is scooby in the animals table and only return the dog column.

use supabase_rs::SupabaseClient;

// always pass an initialized SupabaseClient to the method
let client = SupabaseClient::new(
   "your_supabase_url", "your_supabase_key"
);

async fn select_scooby(
   supabase_client: SupabaseClient
) -> Result<(), String> {

let data: Result<Vec<Value>, String> = supabase_client
   .select("animals")
   .columns(["dog"].to_vec())
   .eq("dog", "scooby")
   .execute()
   .await;

§Select with Count

Counting is very expensive and will be alot slower, so only use it if you need it

This will return all dog rows where the value is scooby in the animals table and count the number of rows that match the filter criteria.

use supabase_rs::SupabaseClient;

// always pass an initialized SupabaseClient to the method
let client = SupabaseClient::new(
  "your_supabase_url", "your_supabase_key"
);

async fn select_scooby_with_count(
  supabase_client: SupabaseClient
) -> Result<(), String> {
 let data: Result<Vec<Value>, String> = supabase_client
   .select("animals")
   .count()
   .execute()
   .await;

§Select with Filter

This will return all dog rows where the value is scooby in the animals table

use supabase_rs::SupabaseClient;

// always pass an initialized SupabaseClient to the method
let client = SupabaseClient::new(
  "your_supabase_url", "your_supabase_key"
);

async fn select_scooby_with_filter(
 supabase_client: SupabaseClient
) -> Result<(), String> {
let data: Result<Vec<Value>, String> = supabase_client
    .select("animals")
    .eq("dog", "scooby")
    .execute()
    .await;

§Selecting with Filter and Count

Counting is very expensive and will be alot slower, so only use it if you need it

This will return all dog rows where the value is scooby in the animals table and count the number of rows that match the filter criteria.

use supabase_rs::SupabaseClient;

// always pass an initialized SupabaseClient to the method
let client = SupabaseClient::new(
 "your_supabase_url", "your_supabase_key"
);

async fn select_scooby_with_filter_and_count(
supabase_client: SupabaseClient
) -> Result<(), String> {
let data: Result<Vec<Value>, String> = supabase_client
    .select("animals")
    .eq("dog", "scooby")
    .count()
    .execute()
    .await;

§Delete

This will delete the row in the test table where the id is 1.

// i know the imports are self explanatory but it makes it easier for beginners:)
use supabase_rs::SupabaseClient;

// always pass an initialized SupabaseClient to the method
let client = SupabaseClient::new(
  "your_supabase_url", "your_supabase_key"
);

async fn delete_example(
 client: SupabaseClient
) -> Result<(), String> {
let delete_result = client
    .delete("test", "1")
    .await;

//!

Experimental features, Not ready for prod!

§Get ID by Column, Cell values

This will return the ID of the row in the specified table where the column matches the provided email.

#[tokio::main]
async fn main() {
    // Initialize the Supabase Client
    let supabase_client = SupabaseClient::new("your_supabase_url", "your_supabase_key");

    let email = "example@email.com".to_string();
    let table_name = "users".to_string();
    let column_name = "email".to_string();
    match supabase_client.get_id(email, table_name, column_name).await {
        Ok(id) => println!("Found ID: {}", id),
        Err(e) => println!("Error: {}", e),
    }
}

§Different Operations

§Update

I’ll be adding more methods and enriching the SDK over the next few weeks, for now!

§Contributers

Modules§

delete
This module provides the functionality to delete rows from a Supabase table.
errors
Error handling
insert
Insert Operations
query
This module contains the QueryBuilder struct and its associated methods for building and executing SQL queries.
query_builder
realtime
request
routing
select
This module contains the select() function
success
Success response types.
tests
update
Update and Upsert Operations

Structs§

SupabaseClient
A client structure for interacting with Supabase services.

Functions§

generate_random_id
Generates a random 64-bit signed integer within a larger range