From 1668de832f40da9e8c6519548ef8a091db4dec20 Mon Sep 17 00:00:00 2001 From: Lumither Tao Date: Thu, 2 May 2024 19:02:13 +0800 Subject: [PATCH] feat(backend) backed init --- .env | 4 +++- app/blog/post/[id]/generate.tsx | 3 +-- app/blog/post/[id]/page.tsx | 4 ++-- backend/.gitignore | 16 +++++++++++++ backend/Cargo.toml | 16 +++++++++++++ backend/post.sql | 7 ++++++ backend/src/api/get_post.rs | 12 ++++++++++ backend/src/api/get_post_list.rs | 18 ++++++++++++++ backend/src/api/mod.rs | 2 ++ backend/src/main.rs | 41 ++++++++++++++++++++++++++++++++ backend/src/model/mod.rs | 12 ++++++++++ backend/tag.sql | 5 ++++ 12 files changed, 135 insertions(+), 5 deletions(-) create mode 100644 backend/.gitignore create mode 100644 backend/Cargo.toml create mode 100644 backend/post.sql create mode 100644 backend/src/api/get_post.rs create mode 100644 backend/src/api/get_post_list.rs create mode 100644 backend/src/api/mod.rs create mode 100644 backend/src/main.rs create mode 100644 backend/src/model/mod.rs create mode 100644 backend/tag.sql diff --git a/.env b/.env index 343fc8c..c65541e 100644 --- a/.env +++ b/.env @@ -1,2 +1,4 @@ BLOG_ENDPOINT=https://raw.githubusercontent.com/lumither/blog-posts/master -; use mirror +BACKEND_PORT=3001 + +DB_CONNECTION=postgresql://localhost:5432/blog diff --git a/app/blog/post/[id]/generate.tsx b/app/blog/post/[id]/generate.tsx index f96c274..12fbae3 100644 --- a/app/blog/post/[id]/generate.tsx +++ b/app/blog/post/[id]/generate.tsx @@ -2,7 +2,6 @@ import React from 'react'; import Markdown from 'react-markdown'; -import { test_markdown } from '@/app/blog/post/[id]/test_markdown'; import { Card, CardBody } from '@nextui-org/card'; import remarkGfm from 'remark-gfm'; import rehypeHighlight from 'rehype-highlight'; @@ -28,7 +27,7 @@ async function Generate(props: Props) { { post_md } diff --git a/app/blog/post/[id]/page.tsx b/app/blog/post/[id]/page.tsx index ee9c1a5..28b0ca0 100644 --- a/app/blog/post/[id]/page.tsx +++ b/app/blog/post/[id]/page.tsx @@ -4,8 +4,8 @@ import Generate from '@/app/blog/post/[id]/generate'; function BlogReader({ params }: { params: { id: string } }) { return ( -
- +
+
); } diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..66a6354 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,16 @@ +### Rust template +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + diff --git a/backend/Cargo.toml b/backend/Cargo.toml new file mode 100644 index 0000000..c573188 --- /dev/null +++ b/backend/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "backend" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +axum = "0.7.5" +dotenv = "0.15.0" +serde = { version = "1.0.199", features = ["derive"] } +serde_json = "1.0.116" +tokio = { version = "1.37.0", features = ["full"] } +uuid = { version = "1.8.0", features = ["v4", "fast-rng", "serde"] } +sqlx = { version = "0.7.4", features = ["runtime-tokio", "tls-native-tls", "postgres", "chrono", "uuid"] } +chrono = { version = "0.4.38", features = ["serde"] } diff --git a/backend/post.sql b/backend/post.sql new file mode 100644 index 0000000..8c7cf26 --- /dev/null +++ b/backend/post.sql @@ -0,0 +1,7 @@ +CREATE TABLE Post +( + post_id UUID PRIMARY KEY, + title VARCHAR(255) NOT NULL, + content TEXT NOT NULL, + last_update TIMESTAMP +); diff --git a/backend/src/api/get_post.rs b/backend/src/api/get_post.rs new file mode 100644 index 0000000..c3b4526 --- /dev/null +++ b/backend/src/api/get_post.rs @@ -0,0 +1,12 @@ +use axum::extract::{Path, State}; +use axum::Json; +use serde_json::Value; +use sqlx::PgPool; + +pub async fn get_post( + State(_db_connection): State, + Path(post_id): Path, +) -> Result, Json> { + dbg!(&post_id); + todo!() +} diff --git a/backend/src/api/get_post_list.rs b/backend/src/api/get_post_list.rs new file mode 100644 index 0000000..3d4a3b0 --- /dev/null +++ b/backend/src/api/get_post_list.rs @@ -0,0 +1,18 @@ +use axum::extract::State; +use axum::Json; +use serde_json::Value; +use sqlx::PgPool; + +use crate::model::Post; + +pub async fn get_post_list( + State(db_connection): State, + Json(_request): Json, +) -> Result, Json> { + let post_list: Vec = sqlx::query_as("select * from post") + .fetch_all(&db_connection) + .await + .unwrap(); + dbg!(&post_list); + Ok(Json::from(serde_json::to_value(post_list).unwrap())) +} diff --git a/backend/src/api/mod.rs b/backend/src/api/mod.rs new file mode 100644 index 0000000..a30b1d7 --- /dev/null +++ b/backend/src/api/mod.rs @@ -0,0 +1,2 @@ +pub mod get_post; +pub mod get_post_list; diff --git a/backend/src/main.rs b/backend/src/main.rs new file mode 100644 index 0000000..3127a2e --- /dev/null +++ b/backend/src/main.rs @@ -0,0 +1,41 @@ +use std::env; +use std::error::Error; + +use axum::Router; +use axum::routing::get; +use dotenv::dotenv; +use sqlx::postgres::PgPoolOptions; + +use crate::api::get_post::get_post; +use crate::api::get_post_list::get_post_list; + +mod api; +mod model; + +#[tokio::main] +async fn main() -> Result<(), Box> { + dotenv()?; + + let port: u32 = match env::var("BACKEND_PORT") { + Ok(value) => value.parse().unwrap(), + Err(_) => 3001, + }; + + let db_connection: String = env::var("DB_CONNECTION")?; + + let db_pool = PgPoolOptions::new() + .connect(&db_connection) + .await + .expect("failed to load database"); + + let app = Router::new() + .route("/api/get/post_list", get(get_post_list)) + .route("/api/get/post/:post_id", get(get_post)) + .with_state(db_pool); + + let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", port)).await?; + + axum::serve(listener, app).await?; + + Ok(()) +} diff --git a/backend/src/model/mod.rs b/backend/src/model/mod.rs new file mode 100644 index 0000000..8d05202 --- /dev/null +++ b/backend/src/model/mod.rs @@ -0,0 +1,12 @@ +use chrono::NaiveDateTime; +use serde::{Deserialize, Serialize}; +use sqlx::FromRow; +use uuid::Uuid; + +#[derive(Debug, Serialize, Deserialize, FromRow)] +pub struct Post { + post_id: Uuid, + title: String, + content: String, + last_update: NaiveDateTime, +} diff --git a/backend/tag.sql b/backend/tag.sql new file mode 100644 index 0000000..3611b09 --- /dev/null +++ b/backend/tag.sql @@ -0,0 +1,5 @@ +CREATE TABLE Tag +( + post_id UUID NOT NULL, + tag VARCHAR(255) NOT NULL +);