Skip to content

Commit

Permalink
feat: Generic header handler (#26)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
gatewaynode committed May 12, 2021
1 parent af5a9a4 commit c46f9bd
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 0 deletions.
71 changes: 71 additions & 0 deletions README.md
Expand Up @@ -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
Expand Down
36 changes: 36 additions & 0 deletions src/builder.rs
Expand Up @@ -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
Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit c46f9bd

Please sign in to comment.