Skip to content

Commit

Permalink
docs: shared db + aws rds feature flag rework (#249)
Browse files Browse the repository at this point in the history
* shared db new feature flags

* aws rds refer to shared db docs

* fix: typo, expand aws rds docs

* chore: update examples in docs
  • Loading branch information
jonaro00 authored Jan 24, 2024
1 parent edb30c3 commit 10db0d3
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 57 deletions.
4 changes: 2 additions & 2 deletions examples/actix-postgres.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ actix-web = "4.3.1"
shuttle-actix-web = "0.36.0"
shuttle-runtime = "0.36.0"
serde = "1.0.148"
shuttle-shared-db = { version = "0.36.0", features = ["postgres"] }
sqlx = { version = "0.6.2", features = ["runtime-tokio-native-tls", "postgres"] }
shuttle-shared-db = { version = "0.36.0", features = ["postgres", "sqlx"] }
sqlx = "0.7.1"
tokio = "1.26.0"
```
</CodeGroup>
Expand Down
4 changes: 2 additions & 2 deletions examples/axum-postgres.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ axum = "0.7.3"
serde = { version = "1.0.188", features = ["derive"] }
shuttle-axum = "0.36.0"
shuttle-runtime = "0.36.0"
shuttle-shared-db = { version = "0.36.0", features = ["postgres"] }
sqlx = { version = "0.7.1", features = ["runtime-tokio-native-tls", "postgres"] }
shuttle-shared-db = { version = "0.36.0", features = ["postgres", "sqlx"] }
sqlx = "0.7.1"
tokio = "1.28.2"
```
</CodeGroup>
Expand Down
4 changes: 2 additions & 2 deletions examples/rocket-postgres.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ edition = "2021"
[dependencies]
rocket = { version = "0.5.0", features = ["json"] }
serde = "1.0.148"
shuttle-shared-db = { version = "0.36.0", features = ["postgres"] }
shuttle-rocket = "0.36.0"
shuttle-runtime = "0.36.0"
sqlx = { version = "0.7.1", features = ["runtime-tokio-native-tls", "postgres"] }
shuttle-shared-db = { version = "0.36.0", features = ["postgres", "sqlx"] }
sqlx = "0.7.1"
tokio = "1.26.0"
```
</CodeGroup>
Expand Down
4 changes: 2 additions & 2 deletions examples/serenity-todo.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,8 @@ serenity = { version = "0.11.5", default-features = false, features = ["client",
shuttle-secrets = "0.36.0"
shuttle-serenity = "0.36.0"
shuttle-runtime = "0.36.0"
shuttle-shared-db = { version = "0.36.0", features = ["postgres"] }
sqlx = { version = "0.6.2", features = ["runtime-tokio-native-tls", "postgres"] }
shuttle-shared-db = { version = "0.36.0", features = ["postgres", "sqlx"] }
sqlx = "0.7.1"
tokio = "1.26.0"
tracing = "0.1.37"
```
Expand Down
79 changes: 54 additions & 25 deletions resources/shuttle-aws-rds.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,28 @@ icon: "aws"

<Snippet file="pro-feature.mdx" />

This plugin provisions databases on AWS RDS using [Shuttle](https://www.shuttle.rs). The following engines are supported:
This plugin provisions AWS RDS databases on [Shuttle](https://www.shuttle.rs). The following engines are supported:
- Postgres
- MySql
- MySQL
- MariaDB

{/* TODO: Write more about the advantages of RDS vs shared */}


## RDS vs Shared DB

- Dedicated Instance: Each instance of AWS RDS is it's own dedicated instance.
- Stability and Security: AWS RDS has greater stability due to it being a service directly offered by AWS, and also greater security due to being a dedicated instance.
- Flexible: AWS RDS instances on the Shuttle platform can be customised to suit your needs. Instance size can be increased from the default and AWS RDS features can be enabled or disabled.

On *AWS RDS* we offer:
- MariaDB
- MySQL
- Postgres
- MySQL
- MariaDB

With the *Shared DB* we offer:
- MongoDB
- Postgres
- MongoDB

## Default RDS Instance

The RDS instance created by Shuttle has the following specifications and features by default:
- 2 vCPU
- 1 GB Memory
Expand All @@ -44,33 +43,63 @@ If you require a different configuration, please contact us on [Discord](https:/
Shuttle makes sure that any data stored in your provisioned database is stored permanently and will persist if you redeploy your server via `cargo shuttle deploy`, as well as if you restart your service via `cargo shuttle project restart`.

## Usage
Add `shuttle-aws-rds` to the dependencies for your service.
Each type of database is behind the following feature flag and attribute path. `*-rustls` feature enables `rustls`-based implementation, otherwise some flavour of `native-tls` is used.

| Engine | Feature flags | Attribute path | Return type |
|----------|---------------|----------------|-------------|
| Postgres | `postgres` or `postgres-rustls` | shuttle_aws_rds::Postgres | `sqlx::PgPool` |
| MySql | `mysql` or `mysql-rustls` | shuttle_aws_rds::MySql | `sqlx::MySqlPool` |
| MariaDB | `mariadb` or `mariadb-rustls` | shuttle_aws_rds::MariaDB | `sqlx::MySqlPool` |
Start by adding `shuttle-aws-rds` to the dependencies for your service.
Each type of database is behind its own feature flag and macro attribute path.

| Engine | Feature flag | Attribute path |
|----------|--------------|----------------|
| Postgres | `postgres` | `shuttle_aws_rds::Postgres` |
| MySQL | `mysql` | `shuttle_aws_rds::MySql` |
| MariaDB | `mariadb` | `shuttle_aws_rds::MariaDB` |

### Output type

By default, you can get the connection string to the database and connect to it with your preferred library.
You can also specify other return types to get rid of common boilerplate.

Depending on which type declaration is used as the output type in the macro, you might need to activate additional feature flags:

| Engine | Feature flag | Type declaration | Description |
|----------|--------------|------------------|-------------|
| Any | | `String` | The connection string including username and password |
| Postgres | `sqlx` (with rustls) or `sqlx-native-tls` | `sqlx::PgPool` | An sqlx connection pool with reasonable defaults |
| MySQL | `sqlx` (with rustls) or `sqlx-native-tls` | `sqlx::MySqlPool` | An sqlx connection pool with reasonable defaults |
| MariaDB | `sqlx` (with rustls) or `sqlx-native-tls` | `sqlx::MySqlPool` | An sqlx connection pool with reasonable defaults |

Lastly, add a macro annotaion to the Shuttle main function. Here are examples for Postgres:

```rust
// Use the connection string
#[shuttle_runtime::main]
async fn main(#[shuttle_aws_rds::Postgres] conn_str: String) -> ... { ... }

// With sqlx feature flag, get a PgPool connected automatically
#[shuttle_runtime::main]
async fn main(#[shuttle_aws_rds::Postgres] pool: sqlx::PgPool) -> ... { ... }
```

### Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| local_uri | str | `None` | If specified, on local runs, connect to this database instead of starting a Docker container for it. |

When setting the `local_uri` you can also insert secrets from `Secrets.toml` using string interpolation. To insert the
`PASSWORD` secret, pass it in like this:
All of the AWS RDS macros take the same optional parameter:

| Parameter | Type | Description |
|-----------|------|-------------|
| local_uri | &str | If specified, on local runs, use this database instead of starting a Docker container for it |

When passing in strings, you can also insert secrets from `Secrets.toml` using string interpolation.
To insert the `PASSWORD` secret, pass it in like this:

```rust
#[shuttle_runtime::main]
async fn tide(
async fn main(
#[shuttle_aws_rds::Postgres(
local_uri = "postgres://postgres:{secrets.PASSWORD}@localhost:16695/postgres"
)] pool: PgPool,
) -> ShuttleTide<MyState> { ... }
)] conn_str: String,
) -> ... { ... }
```

<Note>If you are interpolating a secret from `Secrets.dev.toml`, you need to set the same secret in `Secrets.toml` to a empty string so that this step does not crash in deployment.</Note>
<Note>Caveat: If you are interpolating a secret from `Secrets.dev.toml`, you need to set the same secret in `Secrets.toml` to a empty string so that this step does not crash in deployment.</Note>

The URI should be formatted according to the
[Postgres](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING) or
Expand All @@ -86,7 +115,7 @@ the Docker engine.

## Example

This snippet shows the main function of a tide app that uses the `shuttle_aws_rds::Postgres` attribute to provision an RDS Postgres database.
This snippet shows the main function of a tide app that uses the `#[shuttle_aws_rds::Postgres]` attribute macro to provision an RDS Postgres database.
It gives you an authenticated [sqlx Pool](https://docs.rs/sqlx/latest/sqlx/pool/index.html), which you can use to interact with the database.

```rust main.rs
Expand Down
2 changes: 1 addition & 1 deletion resources/shuttle-persist.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Shuttle Persist"
icon: "key"
icon: "database"
---

The persist plugin allows data to be persisted in a key-value store, which is backed by a struct type. The struct implements `serde::Serialize` for serialization (prepare data for saving or transmission) and `serde::Deserialize` for deserialization (load data to memory, either from storage or fetched via the network). The persist plugin is useful for saving and retrieving data when it is not desired to hard code that data into the app. An example is saved settings for a Discord bot that need to remain the same between updates. State data, used in web frameworks such as Axum and Rocket, is also a good candidate for use of the persist plugin.
Expand Down
70 changes: 50 additions & 20 deletions resources/shuttle-shared-db.mdx
Original file line number Diff line number Diff line change
@@ -1,42 +1,72 @@
---
title: "Shuttle Shared Databases"
icon: "share"
icon: "database"
---

This plugin manages databases on [Shuttle](https://www.shuttle.rs) and connects them to your app. A shared database
will be on the same cluster as other user's databases, but it will not be accessible by other users.
This plugin manages databases on [Shuttle](https://www.shuttle.rs) and connects them to your app.
A shared database is in the same cluster as other user's databases, but it is not accessible by other users.

If you want a high performing and isolated database, consider [Shuttle AWS RDS](./shuttle-aws-rds).

<Tip>You can connect to any type of remotely hosted database you want from your code, so do not let our current database offerings limit your creativity! Got other databases you want to see on Shuttle? Let us know!</Tip>
<Tip>You can connect to any type of remotely hosted database from your code, so do not let our current database offerings limit your creativity! Got other databases you want to see on Shuttle? Let us know!</Tip>

## Usage
Add `shuttle-shared-db` to the dependencies for your service.
Each type of database is behind the following feature flag and attribute path. `*-rustls` feature enables `rustls`-based implementation, otherwise some flavour of `native-tls` is used.

| Engine | Feature flags | Attribute path | Return type |
|----------|---------------|----------------|-------------|
| Postgres | `postgres` or `postgres-rustls` | `shuttle_shared_db::Postgres` | `sqlx::PgPool` |
| MongoDB | `mongodb` (uses rustls) | `shuttle_shared_db::MongoDb` | `mongodb::Database` |
Start by adding `shuttle-shared-db` to the dependencies for your service.
Each type of shareable database is behind its own feature flag and macro attribute path.

| Engine | Feature flag | Attribute path |
|----------|--------------|----------------|
| Postgres | `postgres` | `shuttle_shared_db::Postgres` |
| MongoDB | `mongodb` | `shuttle_shared_db::MongoDb` |

### Output type

By default, you can get the connection string to the database and connect to it with your preferred library.
You can also specify other return types to get rid of common boilerplate.

Depending on which type declaration is used as the output type in the macro, you might need to activate additional feature flags:

| Engine | Feature flag | Type declaration | Description |
|----------|--------------|------------------|-------------|
| Postgres | | `String` | The connection string including username and password |
| Postgres | `sqlx` (with rustls) or `sqlx-native-tls` | `sqlx::PgPool` | An sqlx connection pool with reasonable defaults |
| MongoDB | | `String` | The connection string including username and password |
| MongoDB | | `mongodb::Database` | A client pool connected to the database |

Lastly, add a macro annotaion to the Shuttle main function. Here are examples for Postgres:

```rust
// Use the connection string
#[shuttle_runtime::main]
async fn main(#[shuttle_shared_db::Postgres] conn_str: String) -> ... { ... }

// With sqlx feature flag, get a PgPool connected automatically
#[shuttle_runtime::main]
async fn main(#[shuttle_shared_db::Postgres] pool: sqlx::PgPool) -> ... { ... }
```

### Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| local_uri | str | `None` | If specified, on local runs, connect to this database instead of starting a Docker container for it. |

When setting the `local_uri` you can also insert secrets from `Secrets.toml` using string interpolation. To insert the
`PASSWORD` secret, pass it in like this:
Both the Postgres and MongoDB macros take the same optional parameter:

| Parameter | Type | Description |
|-----------|------|-------------|
| local_uri | &str | If specified, on local runs, use this database instead of starting a Docker container for it |

When passing in strings, you can also insert secrets from `Secrets.toml` using string interpolation.
To insert the `PASSWORD` secret, pass it in like this:

```rust
#[shuttle_runtime::main]
async fn poem(
async fn main(
#[shuttle_shared_db::Postgres(
local_uri = "postgres://postgres:{secrets.PASSWORD}@localhost:16695/postgres"
)] pool: PgPool,
) -> ShuttlePoem<impl poem::Endpoint> { ... }
)] conn_str: String,
) -> ... { ... }
```

<Note>If you are interpolating a secret from `Secrets.dev.toml`, you need to set the same secret in `Secrets.toml` to a empty string so that this step does not crash in deployment.</Note>
<Note>Caveat: If you are interpolating a secret from `Secrets.dev.toml`, you need to set the same secret in `Secrets.toml` to a empty string so that this step does not crash in deployment.</Note>

The URI should be formatted according to the
[Postgres](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING) or
Expand All @@ -52,7 +82,7 @@ the Docker engine.

## Example

The Shuttle poem main function below uses the `[shuttle_shared_db::Postgres]` attribute macro to provision a shared postgres database,
The Shuttle poem main function below uses the `#[shuttle_shared_db::Postgres]` attribute macro to provision a shared Postgres database,
which can be accessed using a pre-configured, authenticated [sqlx Pool](https://docs.rs/sqlx/latest/sqlx/pool/index.html).

```rust main.rs
Expand Down
6 changes: 3 additions & 3 deletions tutorials/databases-with-rust.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Relational databases are the classical way to store data in the backend of web a
To get started with SQLx (and using our new database), we'll want to add the `sqlx` crate to an initialised Rust program. We will also want to add the `shuttle-shared-db` crate which allows us to use the macro that provisions the database instance to us.

```bash
cargo add sqlx shuttle-shared-db --features sqlx/macros,shuttle-shared-db/postgres
cargo add sqlx shuttle-shared-db --features sqlx/macros,shuttle-shared-db/postgres,shuttle-shared-db/sqlx
cargo install sqlx-cli
```

Expand All @@ -24,9 +24,9 @@ id SERIAL PRIMARY KEY NOT NULL,
name VARCHAR NOT NULL,
email VARCHAR NOT NULL,
password VARCHAR NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
```
```

When we run our migrations, this folder will be the default that will be used - when we're ready to run our migrations, we can run `sqlx migrate run --database-url <database-url>`. We can also just run the migrate macro programmatically after connecting to the database:

Expand Down

0 comments on commit 10db0d3

Please sign in to comment.