1 stable release

new 1.6.0 Oct 26, 2024

#438 in Development tools


Used in rp-supabase-client

Apache-2.0 OR MIT

57KB
751 lines

postgrest-rs

Build Crate API License: Apache-2.0 OR MIT

PostgREST client-side library 🦀. This library provides an ORM interface to PostgREST.

Usage

Add this to your Cargo.toml:

[dependencies]
postgrest = "1.0"

Simple example:

use postgrest::Postgrest;

let client = Postgrest::new("https://your.postgrest.endpoint");
let resp = client
    .from("your_table")
    .select("*")
    .execute()
    .await?;
let body = resp
    .text()
    .await?;

Simple example with JWT auth

use postgrest::Postgrest;

let client = Postgrest::new("https://your.postgrest.endpoint");
let resp = client
    .from("your_table")
    .auth("VerySensitiveJWTValueAsStringOrStr")
    .select("*")
    .execute()
    .await?;
let body = resp
    .text()
    .await?;

Simplified example using a custom header (e.g. for API gateway authentication with Supabase).

use postgrest::Postgrest;

let client = Postgrest::new("https://your.supabase.endpoint/rest/v1")
    .insert_header("apikey", "ExampleAPIKeyValue"); // EXAMPLE ONLY!
// Don't actually hard code this value, that's really bad. Use environment
// variables like with the dotenv(https://crates.io/crates/dotenv) crate to inject
let resp = client
    .from("your_table")
    .select("*")
    .execute()
    .await?;
let body = resp
    .text()
    .await?;

Secure example with authenticated API gateway using the dotenv crate to correctly retrieve sensitive values.

use postgrest::Postgrest;
use dotenv;

dotenv::dotenv().ok();

let client = Postgrest::new("https://your.supabase.endpoint/rest/v1")
    .insert_header(
        "apikey",
        dotenv::var("SUPABASE_PUBLIC_API_KEY").unwrap())
let resp = client
    .from("your_table")
    .select("*")
    .execute()
    .await?;
let body = resp
    .text()
    .await?;

if you have RLS enabled you're required to add an extra header for this libary to function correctly.

use postgrest::Postgrest;
use dotenv;

dotenv::dotenv().ok();

let client = Postgrest::new("https://your.supabase.endpoint/rest/v1/")
    .insert_header(
        "apikey",
        dotenv::var("SUPABASE_PUBLIC_API_KEY").unwrap())
    .insert_header("Authorization", format!("Bearer {}", SERVICE_KEY));

let resp = client
    .from("your_table")
    .select("*")
    .execute()
    .await?;
let body = resp
    .text()
    .await?;

Building Queries

These examples assume you've already initialized the client. The methods .from() and .rpc() initalizes the query builder inside the client.

Using filters:

let resp = client
    .from("your_table")
    .eq("country", "Germany")
    .gte("id", "20")
    .select("*")
    .execute()
    .await?;

Updating a table:

let resp = client
    .from("your_table")
    .eq("username", "soedirgo")
    .update("{\"organization\": \"supabase\"}")
    .execute()
    .await?;

Executing stored procedures:

let resp = client
    .rpc("add", "{\"a\": 1, \"b\": 2}")
    .execute()
    .await?;

Not enough filters:

let resp = client
    .from("countries")
    .eq("name", "New Zealand")                        // You can filter for equality...
    .gt("id", "20")
    .lt("id", "20")
    .gte("id", "20")
    .lte("id", "20")
    .like("name", "%United%")                         // ...do pattern matching...
    .ilike("name", "%United%")
    .is("name", "null")
    .in_("name", vec!["China", "France"])
    .neq("name", "China")
    .fts("phrase", "The Fat Cats", Some("english"))   // ...do full text search...
    .plfts("phrase", "The Fat Cats", None)
    .phfts("phrase", "The Fat Cats", Some("english"))
    .wfts("phrase", "The Fat Cats", None)
    .cs("countries", "(10,20)")
    .cd("countries", "(10,20)")
    .ov("population_range", "(100,500)")
    .sl("population_range", (100, 500))               // ...and range operations!
    .sr("population_range", (100, 500))               // Find out more about the filters at:
    .nxl("population_range", (100, 500))              // https://postgrest.org/en/stable/api.html#operators
    .nxr("population_range", (100, 500))
    .adj("population_range", (100, 500))
    .select("*")
    .execute()
    .await?;

Check out the API docs for more info!

Contributing

Contributions are welcome! There might be some features you want in, or some unclear documentation, or a bug—either way, feel free to create an issue, and we'll work it out!

Boring stuff below.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as below, without any additional terms or conditions.

License

Licensed under either of

at your option.


Dependencies

~3–13MB
~173K SLoC