Update backend to allow creating tasks to work with the browser.
This commit is contained in:
parent
d2dfbb9a4a
commit
f3ccc4f194
|
@ -0,0 +1,6 @@
|
|||
CREATE TABLE IF NOT EXISTS task (
|
||||
id integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
title text NOT NULL,
|
||||
description text,
|
||||
CHECK(title <> '')
|
||||
);
|
|
@ -1,8 +1,15 @@
|
|||
use std::sync::Arc;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use serde::Serialize;
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
pub db_pool: Arc<SqlitePool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct FormErrorResponse {
|
||||
pub message: String,
|
||||
pub field_errors: HashMap<String, String>,
|
||||
}
|
||||
|
|
|
@ -24,7 +24,9 @@ async fn main() {
|
|||
.fallback(handle404)
|
||||
.route(
|
||||
"/tasks",
|
||||
get(routes::tasks::list).post(routes::tasks::create),
|
||||
get(routes::tasks::list)
|
||||
.post(routes::tasks::create)
|
||||
.options(routes::tasks::options),
|
||||
)
|
||||
.with_state(state);
|
||||
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use axum::extract::{Json, State};
|
||||
use axum::http::header;
|
||||
use axum::http::StatusCode;
|
||||
use axum::response::IntoResponse;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::global::FormErrorResponse;
|
||||
use crate::{global::AppState, models::Task};
|
||||
|
||||
pub async fn list(state: State<AppState>) -> impl IntoResponse {
|
||||
|
@ -23,6 +26,23 @@ pub struct NewTask {
|
|||
}
|
||||
|
||||
pub async fn create(state: State<AppState>, Json(req): Json<NewTask>) -> impl IntoResponse {
|
||||
if req.title.is_empty() {
|
||||
return (
|
||||
StatusCode::BAD_REQUEST,
|
||||
[(header::ACCESS_CONTROL_ALLOW_ORIGIN, "*")],
|
||||
serde_json::to_string(&FormErrorResponse {
|
||||
message: "Failed to validate new task".to_string(),
|
||||
field_errors: [(
|
||||
"title".to_string(),
|
||||
"Task title must not be empty.".to_string(),
|
||||
)]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect(),
|
||||
})
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
let task = Task::new(req.title, req.description);
|
||||
|
||||
let new_task = task.insert(&state.db_pool).await.unwrap();
|
||||
|
@ -33,3 +53,15 @@ pub async fn create(state: State<AppState>, Json(req): Json<NewTask>) -> impl In
|
|||
serde_json::to_string(&new_task).unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn options() -> impl IntoResponse {
|
||||
(
|
||||
StatusCode::OK,
|
||||
[
|
||||
(header::ACCESS_CONTROL_ALLOW_ORIGIN, "*"),
|
||||
(header::ACCESS_CONTROL_ALLOW_METHODS, "POST, GET, OPTIONS"),
|
||||
(header::ACCESS_CONTROL_ALLOW_HEADERS, "Content-Type"),
|
||||
(header::ACCESS_CONTROL_MAX_AGE, "86400"),
|
||||
],
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue