How do you do pooling properly? #2508
Answered
by
Alfredoes234
Alfredoes234
asked this question in
Q&A
-
Beta Was this translation helpful? Give feedback.
Answered by
Alfredoes234
Jan 12, 2024
Replies: 3 comments 5 replies
-
I have tried to piece it together but it would be useful to have an example for pooling with Axum. |
Beta Was this translation helpful? Give feedback.
1 reply
-
use axum::{
debug_handler,
extract::{Extension, Path, Query, State},
http::StatusCode,
middleware,
response::{Html, Response},
routing::{get, post},
Json, Router,
};
use dotenv::dotenv;
use serde::Deserialize;
use serde_json::{json, Value};
use sqlx::mysql::MySqlPoolOptions;
use sqlx::MySqlPool;
use std::env;
struct AppState {
pool: MySqlPool,
}
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL not set");
let pool = MySqlPoolOptions::new()
.max_connections(5)
.connect(&database_url)
.await
.unwrap();
// build our application with a route
let app = Router::new()
.route("/", get(index))
.route("/api/user_a", post(add_user))
.layer(middleware::map_response(main_response_mapper))
.with_state(pool);
// run it
let listener = tokio::net::TcpListener::bind("localhost:8080")
.await
.unwrap();
println!("listening on http://{}", listener.local_addr().unwrap());
axum::serve(listener, app).await.unwrap();
// Queries
Ok(())
}
async fn main_response_mapper(res: Response) -> Response {
println!("{:<12} - main_response_mapper", "RES_MAPPER");
println!("{res:?}");
res
}
#[derive(serde::Serialize, serde::Deserialize)]
struct UserBody<T> {
user: T,
}
#[derive(serde::Serialize, serde::Deserialize)]
struct User {
name: Option<String>,
email: String,
password: String,
}
#[derive(Debug, Deserialize)]
struct NewUser {
name: Option<String>,
email: String,
password: String,
}
async fn add_user(
State(state): State<AppState>,
Json(params): Json<NewUser>,
) -> Json<UserBody<User>> {
println!("{params:?}");
let result = sqlx::query(
"
INSERT INTO Users(name, email, password)
VALUES (?, ?, ?);
",
)
.bind(¶ms.name)
.bind(¶ms.email)
.bind(¶ms.password)
.execute(&pool)
.await;
match result {
Ok(_) => Json(UserBody {
user: User {
name: params.name,
email: params.email,
password: params.password,
},
}),
Err(_) => panic!(),
}
}
async fn index() -> Html<&'static str> {
println!("{:<12} - main_Site", "HANDLER");
Html("<p>Pirate</p>")
} |
Beta Was this translation helpful? Give feedback.
2 replies
-
What I changed to make it work was. #[derive(Clone)]
struct AppState {
pool: MySqlPool,
}
let pool = MySqlPoolOptions::new()
.max_connections(5)
.connect(&database_url)
.await
.unwrap();
let state = AppState { pool };
let app = Router::new()
.route("/", get(index))
.route("/api/user_a", post(add_user))
.layer(middleware::map_response(main_response_mapper))
.with_state(state);
async fn add_user(
State(pool): State<AppState>,
Json(params): Json<NewUser>,
) -> Json<UserBody<User>> {
println!("{params:?}");
let result = sqlx::query!(
r#"
INSERT INTO Users(name, email, password)
VALUES (?, ?, ?);
"#,
params.name, params.email, params.password,
)
.execute(&pool.pool)
.await;
match result {
Ok(_) => Json(UserBody {
user: User {
name: params.name,
email: params.email,
password: params.password,
},
}),
Err(e) => panic!("{e:?}"),
}
} |
Beta Was this translation helpful? Give feedback.
2 replies
Answer selected by
Alfredoes234
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What I changed to make it work was.