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:
commit
79c245f5c8
8 changed files with 3279 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
/target
|
||||
.shuttle-storage
|
||||
Secrets*.toml
|
||||
.vscode
|
3128
Cargo.lock
generated
Normal file
3128
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
16
Cargo.toml
Normal file
16
Cargo.toml
Normal 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
33
assets/index.html
Normal 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
3
build.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
println!("cargo:rerun-if-changed=migrations");
|
||||
}
|
4
migrations/0001_init.sql
Normal file
4
migrations/0001_init.sql
Normal file
|
@ -0,0 +1,4 @@
|
|||
CREATE TABLE IF NOT EXISTS teas (
|
||||
id serial PRIMARY KEY,
|
||||
teaname TEXT NOT NULL
|
||||
);
|
1
shuttle.toml
Normal file
1
shuttle.toml
Normal file
|
@ -0,0 +1 @@
|
|||
assets = ["assets/*"]
|
90
src/main.rs
Normal file
90
src/main.rs
Normal 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,
|
||||
}
|
Loading…
Add table
Reference in a new issue