4
0
Fork 0
mirror of https://github.com/zzzzDev4/ias-tea-axum.git synced 2025-04-21 07:41:21 +02:00

Initial commit: Axum, Postgres DB setup

This commit is contained in:
zzzz 2024-04-28 21:52:54 +02:00
commit 79c245f5c8
8 changed files with 3279 additions and 0 deletions

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
/target
.shuttle-storage
Secrets*.toml
.vscode

3128
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

16
Cargo.toml Normal file
View file

@ -0,0 +1,16 @@
[package]
name = "ias-tea-axum"
version = "0.1.0"
edition = "2021"
[dependencies]
axum = "0.7.3"
serde = { version = "1.0.188", features = ["derive"] }
shuttle-axum = "0.44.0"
shuttle-runtime = "0.44.0"
shuttle-shared-db = { version = "0.44.0", features = ["postgres", "sqlx"] }
sqlx = "0.7.1"
tokio = "1.28.2"
tower-http = { version = "0.5.0", features = ["fs"] }

33
assets/index.html Normal file
View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>Tea Homepage</title>
</head>
<body>
<p>Tea is great.</p>
<input type="text" id="myInput">
<button id="myButton">Click me if you want tea!</button>
</body>
</html>
<script>
document.getElementById('myButton').addEventListener('click', function() {
var myHeaders = new Headers();
myHeaders.append('Content-Type', 'application/json');
var inputValue = document.getElementById('myInput').value;
var raw = JSON.stringify({ "teaname": inputValue });
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch('https://ias-tea-axum.shuttleapp.rs/tea', requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
});
</script>

3
build.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
println!("cargo:rerun-if-changed=migrations");
}

4
migrations/0001_init.sql Normal file
View file

@ -0,0 +1,4 @@
CREATE TABLE IF NOT EXISTS teas (
id serial PRIMARY KEY,
teaname TEXT NOT NULL
);

1
shuttle.toml Normal file
View file

@ -0,0 +1 @@
assets = ["assets/*"]

90
src/main.rs Normal file
View file

@ -0,0 +1,90 @@
// Invoke-WebRequest -Uri https://ias-tea-axum.shuttleapp.rs/todos -Method POST -Body '{"note":"Earl Grey Premium"}' -ContentType 'application/json'
// cargo shuttle resource delete <type>
// 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<i32>,
State(state): State<MyState>,
) -> Result<impl IntoResponse, impl IntoResponse> {
println!("retrieve");
match sqlx::query_as::<_, Tea>("SELECT * FROM teas 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_all(
State(state): State<MyState>,
) -> Result<impl IntoResponse, impl IntoResponse> {
println!("retrieve all");
match sqlx::query_as::<_, Tea>("SELECT * FROM teas 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<MyState>,
Json(data): Json<TeaNew>,
) -> Result<impl IntoResponse, impl IntoResponse> {
println!("add");
match sqlx::query_as::<_, Tea>("INSERT INTO teas (teaname) VALUES ($1) RETURNING id, teaname")
.bind(&data.teaname)
.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("/tea", post(add))
.route("/tea/:id", get(retrieve))
.route("/alltea", get(retrieve_all))
.with_state(state);
Ok(router.into())
}
#[derive(Deserialize)]
struct TeaNew {
pub teaname: String,
}
#[derive(Serialize, FromRow)]
struct Tea {
pub id: i32,
pub teaname: String,
}