Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update examples to axum 0.7 #243

Merged
merged 1 commit into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions _snippets/check-examples.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<Tip> Be sure to check out the [examples repo](https://github.com/shuttle-hq/shuttle-examples) for many more examples! </Tip>
1 change: 1 addition & 0 deletions _snippets/other-frameworks.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<Tip> If you want to explore other frameworks, we have more examples with popular ones like Tower and Warp. You can find them [right here](/examples/other). </Tip>
4 changes: 2 additions & 2 deletions examples/actix-cookie-authentication.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,6 @@ Looking to extend this example? Here's a couple of ideas to get you started:

---

<Tip> If you want to explore other frameworks, we have more examples with popular ones like Tower and Warp. You can find them [right here](../examples/other). </Tip>
<Snippet file="other-frameworks.mdx" />

<Tip> Be sure to check out the [examples repo](https://github.com/shuttle-hq/shuttle-examples) for many more examples! </Tip>
<Snippet file="check-examples.mdx" />
4 changes: 2 additions & 2 deletions examples/actix-postgres.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,6 @@ Interested in extending this example? Here's as couple of ideas:
- Add static files to show your records
---

<Tip> If you want to explore other frameworks, we have more examples with popular ones like Tower and Warp. You can find them [right here](../examples/other). </Tip>
<Snippet file="other-frameworks.mdx" />

<Tip> Be sure to check out the [examples repo](https://github.com/shuttle-hq/shuttle-examples) for many more examples! </Tip>
<Snippet file="check-examples.mdx" />
4 changes: 2 additions & 2 deletions examples/actix-static-files.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,6 @@ You can extend this example by adding more routes that serve other files.

---

<Tip> If you want to explore other frameworks, we have more examples with popular ones like Tower and Warp. You can find them [right here](../examples/other). </Tip>
<Snippet file="other-frameworks.mdx" />

<Tip> Be sure to check out the [examples repo](https://github.com/shuttle-hq/shuttle-examples) for many more examples! </Tip>
<Snippet file="check-examples.mdx" />
4 changes: 2 additions & 2 deletions examples/actix-websocket-actorless.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,6 @@ Once you've cloned the example, launch it locally using `cargo shuttle run` and

---

<Tip> If you want to explore other frameworks, we have more examples with popular ones like Tower and Warp. You can find them [right here](../examples/other). </Tip>
<Snippet file="other-frameworks.mdx" />

<Tip> Be sure to check out the [examples repo](https://github.com/shuttle-hq/shuttle-examples) for many more examples! </Tip>
<Snippet file="check-examples.mdx" />
4 changes: 2 additions & 2 deletions examples/actix.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ tokio = "1.26.0"

---

<Tip> If you want to explore other frameworks, we have more examples with popular ones like Tower and Warp. You can find them [right here](../examples/other). </Tip>
<Snippet file="other-frameworks.mdx" />

<Tip> Be sure to check out the [examples repo](https://github.com/shuttle-hq/shuttle-examples) for many more examples! </Tip>
<Snippet file="check-examples.mdx" />
77 changes: 44 additions & 33 deletions examples/axum-jwt-authentication.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,50 +17,37 @@ Three Axum routes are registered in this file:
- `/private`: a route that can only be accessed with a valid JWT.

You can clone the example below by running the following (you'll need `cargo-shuttle` installed):
```bash

```bash
cargo shuttle init --from shuttle-hq/shuttle-examples \
--subfolder axum/jwt-authentication
--subfolder axum/jwt-authentication
```

## Code

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

[dependencies]
axum = { version = "0.6.18", features = ["headers"] }
jsonwebtoken = "8.3.0"
once_cell = "1.18.0"
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0.107"
shuttle-axum = "0.27.0"
shuttle-runtime = "0.27.0"
tokio = "1.28.2"
tracing-subscriber = "0.3.17"
```
Your `main.rs` should look like this:

```Rust main.rs
<CodeGroup>
```rust main.rs
use axum::{
async_trait,
extract::FromRequestParts,
headers::{authorization::Bearer, Authorization},
http::{request::Parts, StatusCode},
response::{IntoResponse, Response},
routing::{get, post},
Json, RequestPartsExt, Router, TypedHeader,
Json, RequestPartsExt, Router,
};
use axum_extra::{
headers::{authorization::Bearer, Authorization},
TypedHeader,
};
use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use serde_json::json;
use std::fmt::Display;
use std::time::SystemTime;

static KEYS: Lazy<Keys> = Lazy::new(|| {
// note that in production, you will probably want to use a random SHA-256 hash or similar
// note that in production, you will probably want to use a random SHA-256 hash or similar
let secret = "JWT_SECRET".to_string();
Keys::new(secret.as_bytes())
});
Expand Down Expand Up @@ -98,13 +85,17 @@ async fn login(Json(payload): Json<AuthPayload>) -> Result<Json<AuthBody>, AuthE
}

// add 5 minutes to current unix epoch time as expiry date/time
let exp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).as_secs() + 300;

let exp = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs()
+ 300;

let claims = Claims {
sub: "[email protected]".to_owned(),
company: "ACME".to_owned(),
// Mandatory expiry time as UTC timestamp
exp: usize::try_from(exp).unwrap()
// Mandatory expiry time as UTC timestamp - takes unix epoch
exp: usize::try_from(exp).unwrap(),
};
// Create the authorization token
let token = encode(&Header::default(), &claims, &KEYS.encoding)
Expand Down Expand Up @@ -170,7 +161,7 @@ impl IntoResponse for AuthError {
}
}

// encoding/decoding keys - set in the static `once_cell` above
// encoding/decoding keys - set in the static `once_cell` above
struct Keys {
encoding: EncodingKey,
decoding: DecodingKey,
Expand Down Expand Up @@ -207,7 +198,7 @@ struct AuthPayload {
client_secret: String,
}

// error types for auth errors
// error types for auth errors
#[derive(Debug)]
enum AuthError {
WrongCredentials,
Expand All @@ -217,6 +208,26 @@ enum AuthError {
}
```

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

[dependencies]
axum = "0.7.3"
axum-extra = { version = "0.9.1", features = ["typed-header"] }
jsonwebtoken = "8.3.0"
once_cell = "1.18.0"
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0.107"
shuttle-axum = "0.35.0"
shuttle-runtime = "0.35.0"
tokio = "1.28.2"
tracing-subscriber = "0.3.17"
```
</CodeGroup>

## Usage

Once you've cloned this example, launch it locally by using `cargo shuttle run`. Once you've verified that it's up, you'll now be able to go to `http://localhost:8000` and start trying the example out!
Expand Down Expand Up @@ -256,6 +267,6 @@ Looking to extend this example? Here's a couple of ideas to get you started:

---

<Tip> If you want to explore other frameworks, we have more examples with popular ones like Tower and Warp. You can find them [right here](../examples/other). </Tip>
<Snippet file="other-frameworks.mdx" />

<Tip> Be sure to check out the [examples repo](https://github.com/shuttle-hq/shuttle-examples) for many more examples! </Tip>
<Snippet file="check-examples.mdx" />
83 changes: 38 additions & 45 deletions examples/axum-postgres.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,61 @@ title: "Postgres Todo App"
description: "This article walks you through how you can easily set up a simple to-do app using Axum and SQLx with PostgresQL."
---

## Description
## Description
This example shows how to make a simple TODO app using Axum and a shared Shuttle Postgres DB.

The following routes are provided:
- GET `/todos/<id>` - Get a to-do item by ID.
- POST `/todos` - Create a to-do item. Takes "note" as a JSON body parameter.

You can clone the example below by running the following (you'll need `cargo-shuttle` installed):
```bash

```bash
cargo shuttle init --from shuttle-hq/shuttle-examples \
--subfolder axum/postgres
--subfolder axum/postgres
```

## Code

<CodeGroup>
```rust src/main.rs
use axum::{Json,
extract::{Path, State},
http::StatusCode,
response::IntoResponse,
Router,
routing::{post, get}};
use axum::{
extract::{Path, State},
http::StatusCode,
response::IntoResponse,
routing::{get, post},
Json, Router,
};
use serde::{Deserialize, Serialize};
use shuttle_runtime::CustomError;
use sqlx::{FromRow, PgPool};

async fn retrieve(
Path(id): Path<i32>,
State(state): State<MyState>
) -> Result<impl IntoResponse, impl IntoResponse> {
Path(id): Path<i32>,
State(state): State<MyState>,
) -> Result<impl IntoResponse, impl IntoResponse> {
match sqlx::query_as::<_, Todo>("SELECT * FROM todos WHERE id = $1")
.bind(id)
.fetch_one(&state.pool)
.await {
Ok(todo) => Ok((StatusCode::OK, Json(todo))),
Err(e) => Err((StatusCode::BAD_REQUEST, e.to_string()))
}
.await
{
Ok(todo) => Ok((StatusCode::OK, Json(todo))),
Err(e) => Err((StatusCode::BAD_REQUEST, e.to_string())),
}
}

async fn add(
State(state): State<MyState>,
Json(data): Json<TodoNew>,
) -> Result<impl IntoResponse, impl IntoResponse> {
match sqlx::query_as::<_, Todo>(
"INSERT INTO todos (note) VALUES ($1) RETURNING id, note"
).bind(&data.note)
match sqlx::query_as::<_, Todo>("INSERT INTO todos (note) VALUES ($1) RETURNING id, note")
.bind(&data.note)
.fetch_one(&state.pool)
.await {
Ok(todo) => Ok((StatusCode::CREATED, Json(todo))),
Err(e) => Err((StatusCode::BAD_REQUEST, e.to_string()))
}
.await
{
Ok(todo) => Ok((StatusCode::CREATED, Json(todo))),
Err(e) => Err((StatusCode::BAD_REQUEST, e.to_string())),
}
}

#[derive(Clone)]
Expand All @@ -63,17 +66,16 @@ struct MyState {
}

#[shuttle_runtime::main]
async fn axum(
#[shuttle_shared_db::Postgres] pool: PgPool
) -> shuttle_axum::ShuttleAxum {
sqlx::migrate!().run(&pool)
async fn axum(#[shuttle_shared_db::Postgres] pool: PgPool) -> shuttle_axum::ShuttleAxum {
sqlx::migrate!()
.run(&pool)
.await
.map_err(CustomError::new)?;

let state = MyState { pool };
let router = Router::new()
.route("/todos", post(add))
.route("/todos/:id", get(retrieve))
.route("/todos/:id", get(retrieve))
.with_state(state);

Ok(router.into())
Expand All @@ -91,29 +93,20 @@ struct Todo {
}
```

```sql migrations/1_schema.sql
DROP TABLE IF EXISTS todos;

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

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

[dependencies]
axum = "0.6.18"
serde = { version = "1.0.148", features = ["derive"] }
shuttle-shared-db = { version = "0.27.0", features = ["postgres"] }
shuttle-axum = "0.27.0"
shuttle-runtime = "0.27.0"
axum = "0.7.3"
serde = { version = "1.0.188", features = ["derive"] }
shuttle-axum = "0.35.0"
shuttle-runtime = "0.35.0"
shuttle-shared-db = { version = "0.35.0", features = ["postgres"] }
sqlx = { version = "0.7.1", features = ["runtime-tokio-native-tls", "postgres"] }
tokio = "1.26.0"
tokio = "1.28.2"
```
</CodeGroup>

Expand All @@ -137,6 +130,6 @@ Interested in extending this example? Here's as couple of ideas:
- Add static files to show your records
---

<Tip> If you want to explore other frameworks, we have more examples with popular ones like Tower and Warp. You can find them [right here](../examples/other). </Tip>
<Snippet file="other-frameworks.mdx" />

<Tip> Be sure to check out the [examples repo](https://github.com/shuttle-hq/shuttle-examples) for many more examples! </Tip>
<Snippet file="check-examples.mdx" />
17 changes: 8 additions & 9 deletions examples/axum-static-files.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,16 @@ This example has one route at `/` where the homepage is served and shows you how
Note that static assets are declared in the `Shuttle.toml` file.

You can clone the example below by running the following (you'll need `cargo-shuttle` installed):

```bash
cargo shuttle init --from shuttle-hq/shuttle-examples \
--subfolder axum/static-files
--subfolder axum/static-files
```

## Code

<CodeGroup>
```rust src/main.rs
use std::path::PathBuf;

use axum::{routing::get, Router};
use tower_http::services::ServeDir;

Expand All @@ -29,10 +28,10 @@ async fn hello_world() -> &'static str {
}

#[shuttle_runtime::main]
async fn axum() -> shuttle_axum::ShuttleAxum {
async fn main() -> shuttle_axum::ShuttleAxum {
let router = Router::new()
.route("/", get(hello_world))
.nest_service("/assets", ServeDir::new(PathBuf::from("assets")));
.nest_service("/assets", ServeDir::new("assets"));

Ok(router.into())
}
Expand All @@ -58,11 +57,11 @@ edition = "2021"
publish = false

[dependencies]
axum = "0.6.18"
axum = "0.7.3"
shuttle-axum = "0.35.0"
shuttle-runtime = "0.35.0"
tokio = "1.28.2"
tower-http = { version = "0.4.0", features = ["fs"] }
tower-http = { version = "0.5.0", features = ["fs"] }
```

```toml Shuttle.toml
Expand All @@ -78,6 +77,6 @@ You can extend this example by adding more routes that serve other files.

---

<Tip> If you want to explore other frameworks, we have more examples with popular ones like Tower and Warp. You can find them [right here](../examples/other). </Tip>
<Snippet file="other-frameworks.mdx" />

<Tip> Be sure to check out the [examples repo](https://github.com/shuttle-hq/shuttle-examples) for many more examples! </Tip>
<Snippet file="check-examples.mdx" />
Loading