1. Examples
  2. Tide

Hello world!

Simple ‘Hello world’ app using Tide.

Create a new directory (mkdir) and move into it (cd) — afterwards, execute the following command to initialize shuttle inside with the Tide boilerplate.

cargo shuttle init --tide

Make sure that your Cargo.toml file looks like the one below — having the right dependencies is key!

Cargo.toml
[package]
name = "hello-world"
version = "0.1.0"
edition = "2021"

[lib]

[dependencies]
shuttle-service = { version = "0.9.0", features = ["web-tide"] }
tide = "0.16.0"

Your lib.rs should look like this:

lib.rs
#[shuttle_service::main]
async fn tide() -> shuttle_service::ShuttleTide<()> {
    let mut app = tide::new();
    app.with(tide::log::LogMiddleware::new());

    app.at("/hello").get(|_| async { Ok("Hello, world!") });

    Ok(app)
}

Finally, to deploy your app, all you need to do is:

cargo shuttle deploy

And your app is live! 🎉🎉🎉

AWS RDS Postgres

Create a new directory (mkdir) and move into it (cd) — afterwards, execute the following command to initialize shuttle inside with the Tide boilerplate.

cargo shuttle init --tide

Make sure that your Cargo.toml file looks like the one below — having the right dependencies is key!

Cargo.toml
[package]
name = "postgres"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = { version = "1.0", features = ["derive"] }
shuttle-aws-rds = { version = "0.9.0", features = ["postgres"] }
shuttle-service = { version = "0.9.0", features = ["web-tide"] }
sqlx = { version = "0.6", features = ["runtime-tokio-native-tls", "postgres"] }
tide = "0.16.0"

Your lib.rs should look like this:

lib.rs
use serde::{Deserialize, Serialize};
use shuttle_service::{error::CustomError, ShuttleTide};
use sqlx::{Executor, FromRow, PgPool};
use tide::{Body, Request};

async fn retrieve(req: Request<MyState>) -> tide::Result {
    let id: i32 = req.param("id")?.parse()?;
    let todo: Todo = sqlx::query_as("SELECT * FROM todos WHERE id = $1")
        .bind(id)
        .fetch_one(&req.state().pool)
        .await?;

    Body::from_json(&todo).map(Into::into)
}

async fn add(mut req: Request<MyState>) -> tide::Result {
    let data: TodoNew = req.body_json().await?;
    let todo: Todo = sqlx::query_as("INSERT INTO todos(note) VALUES ($1) RETURNING id, note")
        .bind(&data.note)
        .fetch_one(&req.state().pool)
        .await?;

    Body::from_json(&todo).map(Into::into)
}

#[derive(Clone)]
struct MyState {
    pool: PgPool,
}

#[shuttle_service::main]
async fn tide(#[shuttle_aws_rds::Postgres] pool: PgPool) -> ShuttleTide<MyState> {
    pool.execute(include_str!("../schema.sql"))
        .await
        .map_err(CustomError::new)?;

    let state = MyState { pool };
    let mut app = tide::with_state(state);

    app.with(tide::log::LogMiddleware::new());
    app.at("/todo").post(add);
    app.at("/todo/:id").get(retrieve);

    Ok(app)
}


#[derive(Deserialize)]
struct TodoNew {
    pub note: String,
}

#[derive(Serialize, FromRow)]
struct Todo {
    pub id: i32,
    pub note: String,
}

And your schema.sql should look like this:

schema.sql
DROP TABLE IF EXISTS todos;

CREATE TABLE todos (
  id serial PRIMARY KEY,
  note TEXT NOT NULL
);

Finally, to deploy your app, all you need to do is:

cargo shuttle deploy

And your app is live! 🎉🎉🎉