From c46f9bd80429c123da3fc798b22d66f26cf4d2d4 Mon Sep 17 00:00:00 2001 From: gatewaynode <44749714+gatewaynode@users.noreply.github.com> Date: Tue, 11 May 2021 22:16:08 -0400 Subject: [PATCH] feat: Generic header handler (#26) * Added a builder method to add arbitrary headers one by one. * Updated README with examples of auth() and insert_header() and section leading text about query building. --- README.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/builder.rs | 36 +++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/README.md b/README.md index f7ac042..cdd9aa3 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,77 @@ let body = resp .await?; ``` +Simple example with JWT auth + +```rust +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 an authenticated API gateway and JWT authorization (like SupaBase). + +```rust +use postgrest::Postgrest; + +static HEADER_KEY: &str = "apikey"; +let header_value: String = "ExampleAPIKeyValue".to_string(); // 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 client = Postgrest::new("https://your.supabase.endpoint/rest/v1/"); +let resp = client + .from("your_table") + .auth(header_value) + .insert_header(HEADER_KEY, header_value) + .select("*") + .execute() + .await?; +let body = resp + .text() + .await?; + +``` + +**Secure** example with authenticated API gateway and JWT authorization using the dotenv crate to correctly retrieve sensitive values. + +```rust +use postgrest::Postgrest; +use dotenv; + +dotenv().ok(); + +static HEADER_KEY: &str = "apikey"; + +let client = Postgrest::new("https://your.supabase.endpoint/rest/v1/"); +let resp = client + .from("your_table") + .auth(env::var("supabase_public_api_key").unwrap().to_string())) + .insert_header( + HEADER_KEY, + env::var("supabase_public_api_key").unwrap().to_string()) + .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: ```rust diff --git a/src/builder.rs b/src/builder.rs index 323b4d7..160b15e 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -59,6 +59,31 @@ impl Builder { self } + /// Add arbitrary headers to the request. For instance when you may want to connect + /// through an api gateway that needs an API key header in addition to the JWT. + /// + /// # Example + /// + /// ``` + /// use postgrest::Postgrest; + /// + /// static header_name: &'static str = "foo"; + /// let header_value: String = "bar".to_string(); + /// + /// let client = Postgrest::new("https://your.postgrest.endpoint/rest/v1/"); + /// client + /// .from("table") + /// .insert_header(header_name, header_value); + /// ``` + pub fn insert_header(mut self, header_name: &'static str, header_value: String) -> Self { + self.headers.insert( + header_name, + HeaderValue::from_str(&header_value) + .expect("Couldn't convert supplied header value from String to str."), + ); + self + } + /// Performs horizontal filtering with SELECT. /// /// # Note @@ -469,6 +494,17 @@ mod tests { ); } + #[test] + fn with_insert_header() { + static A_HEADER_KEY: &str = "foo"; + let a_header_value: String = "bar".to_string(); + let builder = Builder::new(TABLE_URL, None).insert_header(A_HEADER_KEY, a_header_value); + assert_eq!( + builder.headers.get("foo").unwrap(), + HeaderValue::from_static("bar") + ); + } + #[test] fn select_assert_query() { let builder = Builder::new(TABLE_URL, None).select("some_table");