Skip to content

Commit

Permalink
update examples to axum 0.7 (#243)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaro00 authored Jan 9, 2024
1 parent e5a323b commit 4a7fb05
Show file tree
Hide file tree
Showing 17 changed files with 130 additions and 135 deletions.
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

0 comments on commit 4a7fb05

Please sign in to comment.