mabel/src/routes/sites.rs

63 lines
1.5 KiB
Rust

use axum::{
extract::{Path, State},
response::IntoResponse,
routing::{get, post},
Json, Router,
};
use serde::Deserialize;
use serde_json::json;
use std::sync::Arc;
use crate::{
auth::http::RequireUser,
content::Site,
http::{
error::{ApiError, ERR_NOT_FOUND},
extract::JsonBody,
},
state::AppState,
};
async fn get_site(
State(state): State<Arc<AppState>>,
Path(name): Path<String>,
) -> Result<impl IntoResponse, ApiError<'static>> {
let site_query = sqlx::query_as("SELECT * FROM sites WHERE name = $1").bind(name);
let site: Site = site_query
.fetch_one(&state.database)
.await
.map_err(|e| match e {
sqlx::Error::RowNotFound => ERR_NOT_FOUND,
_ => e.into(),
})?;
Ok(Json(site))
}
#[derive(Deserialize)]
struct CreateSiteRequest {
name: String,
title: String,
}
async fn create_site(
State(state): State<Arc<AppState>>,
RequireUser(user): RequireUser,
JsonBody(payload): JsonBody<CreateSiteRequest>,
) -> Result<impl IntoResponse, ApiError<'static>> {
sqlx::query!(
"INSERT INTO sites (name, owner, title) VALUES ($1, $2, $3)",
payload.name,
user.id,
payload.title,
)
.execute(&state.database)
.await?;
Ok(Json(json!({"ok": true, "url": "test"})))
}
pub fn router() -> Router<Arc<AppState>> {
Router::new()
.route("/", post(create_site))
.route("/:name", get(get_site))
}