// Invoke-WebRequest -Uri https://ias-tea-axum.shuttleapp.rs/alltea -Method POST -Body '{"note":"Earl Grey Premium"}' -ContentType 'application/json' // cargo shuttle resource delete database::shared::postgres // cargo shuttle resource list use axum::{ extract::{Path, State}, http::StatusCode, response::IntoResponse, routing::{get, post}, Json, Router, }; use serde::{Deserialize, Serialize}; use sqlx::{FromRow, PgPool}; use tower_http::services::ServeFile; async fn retrieve( Path(id): Path, State(state): State, ) -> Result { println!("retrieve"); match sqlx::query_as::<_, Tea>("SELECT * FROM tea WHERE id = $1") .bind(id) .fetch_one(&state.pool) .await { Ok(tea) => Ok((StatusCode::OK, Json(tea))), Err(e) => Err((StatusCode::BAD_REQUEST, e.to_string())), } } async fn retrieve_by_rfid( Path(rfid): Path, State(state): State, ) -> Result { println!("retrieve by rfid"); match sqlx::query_as::<_, Tea>("SELECT * FROM tea WHERE rfidcode = $1 LIMIT 1") .bind(rfid) .fetch_optional(&state.pool) .await { Ok(tea) => Ok((StatusCode::OK, Json(tea))), Err(e) => Err((StatusCode::BAD_REQUEST, e.to_string())), } } async fn retrieve_all( State(state): State, ) -> Result { println!("retrieve all"); match sqlx::query_as::<_, Tea>("SELECT * FROM tea LIMIT 100") .fetch_all(&state.pool) .await { Ok(all_tea) => Ok((StatusCode::OK, Json(all_tea))), Err(e) => Err((StatusCode::BAD_REQUEST, e.to_string())), } } async fn add( State(state): State, Json(data): Json, ) -> Result { println!("add"); match sqlx::query_as::<_, Tea>("INSERT INTO tea (teaname, rfidcode, watertemp, steepingseconds) VALUES ($1, $2, $3, $4) RETURNING id, teaname, rfidcode, watertemp, steepingseconds") .bind(&data.teaname) .bind(&data.rfidcode) .bind(&data.watertemp) .bind(&data.steepingseconds) .fetch_one(&state.pool) .await { Ok(tea) => Ok((StatusCode::CREATED, Json(tea))), Err(e) => Err((StatusCode::BAD_REQUEST, e.to_string())), } } #[derive(Clone)] struct MyState { pool: PgPool, } #[shuttle_runtime::main] async fn main(#[shuttle_shared_db::Postgres] pool: PgPool) -> shuttle_axum::ShuttleAxum { sqlx::migrate!() .run(&pool) .await .expect("Failed to run migrations"); let state = MyState { pool }; let router = Router::new() .nest_service("/", ServeFile::new("assets/index.html")) .route("/addtea", post(add)) .route("/tea/:id", get(retrieve)) .route("/teabyrfid/:rfid", get(retrieve_by_rfid)) .route("/alltea", get(retrieve_all)) .with_state(state); Ok(router.into()) } #[derive(Deserialize)] struct TeaNew { pub teaname: String, pub rfidcode: String, pub watertemp: i32, pub steepingseconds: i32, } #[derive(Serialize, FromRow)] struct Tea { pub id: i32, pub teaname: String, pub rfidcode: String, pub watertemp: i32, pub steepingseconds: i32, }