Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cycle5: easy_note to rust, hertz_handler/demoapi package #87

Open
wants to merge 1 commit into
base: feat/go_to_rust_cycle4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go_to_rust/easy_note/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ serde = "*"
tracing = "*"
motore = "*"
serde_json = "*"
mime = "*"

[profile.release]
opt-level = 3
Expand Down
270 changes: 233 additions & 37 deletions go_to_rust/easy_note/src/cmd/api/hertz_handler/demoapi/mod.rs
Original file line number Diff line number Diff line change
@@ -1,63 +1,259 @@
use std::convert::Infallible;
use serde_json::json;
use volo::context::Context;
use volo_http::context::ServerContext;
use volo_http::http;
use volo_http::http::StatusCode;
use volo_http::request::ServerRequest;
use volo_http::response::ServerResponse;
use volo_http::http;
use volo_http::server::IntoResponse;
use volo_http::json::Json;
use volo_http::server::extract::FromRequest;
use volo_http::server::response::IntoResponse;
use volo_http::http::Response as http_response;
use std::convert::Infallible;
use crate::cmd::api::mw::JWT_MIDDLEWARE;
use crate::cmd::api::rpc::create_note as rpc_create_note;
use crate::cmd::api::rpc;
use crate::pkg::errno;
use crate::pkg::consts;
use crate::pkg::errno::ErrNo;
use serde::Serialize;
use serde::Deserialize;

// mock for implement stage
// CheckUser函数用于处理用户登录请求,通过JwtMiddleware的LoginHandler方法进行JWT认证和授权。
pub async fn check_user(
_cx: &mut ServerContext, // 上下文 context
_req: ServerRequest, // 用户请求
cx: &mut ServerContext,
req: ServerRequest,
) -> Result<ServerResponse, Infallible> {
// todo!("implement user login logic");
Ok("todo".into_response())
// 调用JwtMiddleware的LoginHandler方法,处理用户登录请求并进行JWT认证和授权
JWT_MIDDLEWARE.login_handler(cx, req).await
}

// mock for implement stage
#[derive(Serialize, Deserialize)]
pub struct Response {
code: i64,
message: String,
data: String,
}

// CreateNote函数的主要功能是创建一条新笔记记录,并将结果返回给客户端。
pub async fn create_note(
_cx: &mut ServerContext, // 上下文 context
_req: ServerRequest, // 用户请求
cx: &mut ServerContext,
req: ServerRequest,
) -> Result<ServerResponse, Infallible> {
// todo!("implement user login logic");
Ok("todo".into_response())
// 1. 从请求上下文中绑定并验证请求数据
let (parts, body) = req.into_parts();
let data = match Json::<NoteData>::from_request(cx, parts, body).await {
Ok(data) => data,
Err(err) => {
// 2. 如果验证失败,将错误信息转换为特定错误类型,并返回给客户端
let err = ErrNo::default();
return Ok(send_response(cx, err, "Invalid data".to_string()).await.into_response());
}
};

// 3. 从请求上下文中获取用户身份信息
let user_identity = cx.extensions().get::<String>().expect("Identity not found");

// 4. 调用远程过程创建笔记记录
match rpc_create_note(user_identity, data).await {
Ok(_) => {
// 6. 如果操作成功,返回成功状态给客户端
let err = ErrNo::default();
Ok(send_response(cx, err, "Note created successfully".to_string()).await.into_response())
}
Err(err) => {
// 5. 如果创建笔记过程中发生错误,将错误信息转换为特定错误类型,并返回给客户端
let err = ErrNo::default();
Ok(send_response(cx, err, "Failed to create note".to_string()).await.into_response())
}
}
}

// mock struct for NoteData, replace with actual structure
#[derive(Debug, Deserialize)]
struct NoteData {
// fields for note data
}

// mock for implement stage
#[derive(Debug, Deserialize)]
struct CreateUserRequest {
// Define the fields based on your requirements
}

// CreateUser handles the user creation request
pub async fn create_user(
_cx: &mut ServerContext, // 上下文 context
_req: ServerRequest, // 用户请求
cx: &mut ServerContext,
req: ServerRequest,
) -> Result<ServerResponse, Infallible> {
// todo!("implement user login logic");
Ok("todo".into_response())
let (parts, body) = req.into_parts();

// 1. 使用请求上下文中的方法绑定并验证创建用户请求数据
let create_user_req = match Json::<CreateUserRequest>::from_request(cx, parts, body).await {
Ok(data) => data,
Err(err) => {
// 2. 如果验证失败,转换错误并发送错误响应给客户端
let err = ErrNo::default();
return Ok(send_response(cx, err, "Invalid data".to_string()).await.into_response());
}
};

// 3. 调用RPC服务创建用户
match rpc::create_user(cx, create_user_req).await {
Ok(_) => {
// 5. 如果创建成功,发送成功状态响应给客户端
let err = ErrNo::default();
Ok(send_response(cx, err, "successfully".to_string()).await.into_response())
}
Err(err) => {
// 4. 如果创建失败,转换错误并发送错误响应给客户端
let err = ErrNo::default();
Ok(send_response(cx, err, "failed to create user".to_string()).await.into_response())
}
}
}
// mock for implement stage

// DeleteNote函数的主要功能是处理删除笔记的请求。
pub async fn delete_note(
_cx: &mut ServerContext, // 上下文 context
_req: ServerRequest, // 用户请求
cx: &mut ServerContext,
req: ServerRequest,
) -> Result<ServerResponse, Infallible> {
// todo!("implement user login logic");
Ok("todo".into_response())
// 1. 从请求上下文中绑定并验证请求数据
let (parts, body) = req.into_parts();
let request_data = match Json::<NoteRequest>::from_request(cx, parts, body).await {
Ok(data) => data,
Err(err) => {
// 2. 如果绑定或验证失败,转换错误信息并通过请求上下文返回给客户端
let err = ErrNo::default();
return Ok(send_response(cx, err, "Invalid data".to_string()).await.into_response());
}
};

// 3. 从请求上下文中获取用户身份信息
let identity = cx.extensions().get::<String>().cloned().unwrap_or_default();

// 4. 调用RPC接口删除指定笔记
match rpc::delete_note(&identity, &request_data.0.note_id).await {
Ok(_) => {
// 5. 如果删除成功,返回成功状态给客户端
let err = ErrNo::default();
Ok(send_response(cx, err, "successfully".to_string()).await.into_response())
}
Err(err) => {
// 6. 如果删除过程中出现错误,转换错误信息并通过请求上下文返回给客户端
let err = ErrNo::default();
Ok(send_response(cx, err, "failed tp delete note".to_string()).await.into_response())
}
}
}
// mock for implement stage

// Mock struct for NoteRequest
#[derive(Debug, Deserialize)]
struct NoteRequest {
note_id: String,
}

// QueryNote函数的主要功能是处理查询笔记的请求。
pub async fn query_note(
_cx: &mut ServerContext, // 上下文 context
_req: ServerRequest, // 用户请求
cx: &mut ServerContext,
req: ServerRequest,
) -> Result<ServerResponse, Infallible> {
// todo!("implement user login logic");
Ok("todo".into_response())
}
// 1. 定义错误变量err和请求变量req
let mut err = None;
let mut request_data = Json::default();

// mock for implement stage
pub fn send_response(_err: &'static str, _msg: &'static str) -> (http::StatusCode, &'static str) {
(http::StatusCode::INTERNAL_SERVER_ERROR, _msg)
// 2. 调用请求上下文的BindAndValidate方法绑定并验证请求数据
let (parts, body) = req.into_parts();
match Json::from_request(cx, parts, body).await {
Ok(data) => request_data = data,
Err(e) => {
// 3. 如果验证失败,调用SendResponse函数返回错误响应
let err = ErrNo::default();
return Ok(send_response(cx, err, "Invalid data".to_string()).await.into_response());
}
}

// 4. 从请求上下文中获取用户身份信息
let user_id: String = cx
.extensions()
.get::<String>()
.cloned()
.unwrap_or_default();

// 5. 调用QueryNotes函数查询笔记,传入用户ID、搜索关键字、偏移量和限制量
match rpc::query_notes(user_id, request_data).await {
Ok(response) => {
let err = ErrNo::default();
Ok(send_response(cx, err, "successfully".to_string()).await.into_response())
}

Err(e) => {
// 6. 如果查询出错,调用SendResponse函数返回错误响应
let err = ErrNo::default();
Ok(send_response(cx, err, "failed to query note".to_string()).await.into_response())
}
}
}

// mock for implement stage

pub async fn update_note(
_cx: &mut ServerContext, // 上下文 context
_req: ServerRequest, // 用户请求
cx: &mut ServerContext,
req: ServerRequest,
) -> Result<ServerResponse, Infallible> {
// todo!("implement user login logic");
Ok("todo".into_response())
}
// 2. 使用请求上下文的BindAndValidate方法绑定并验证请求数据到请求数据结构

let (parts, body) = req.into_parts();
let data = match Json::<UpdateNoteRequest>::from_request(cx, parts, body).await {
Ok(data) => data,
Err(_) => {
let err = ErrNo::default();
return Ok(send_response(cx, err, "Invalid data".to_string()).await.into_response());
}
};

// 4. 从请求上下文中获取用户身份信息
let user_identity = cx
.extensions()
.get::<String>()
.unwrap_or(&consts::IDENTITY_KEY.to_string())
.clone();

// 5. 调用rpc.UpdateNote函数更新笔记内容
match rpc::update_note(&user_identity, &data).await {
Ok(_) => {
// 7. 如果更新成功,调用SendResponse函数返回成功响应
let err = ErrNo::default();
Ok(send_response(cx, err, "successfully".to_string()).await.into_response())
}
Err(e) => {
// 6. 如果更新失败,调用SendResponse函数返回错误响应
let err = ErrNo::default();
Ok(send_response(cx, err, "failed to update note".to_string()).await.into_response())
}
}
}

pub async fn send_response(
_cx: &mut ServerContext,
err_no: errno::ErrNo,
data: String,
) -> Result<http_response<String>, Infallible> {
let res = Response{
code: err_no.err_code,
message: err_no.err_msg,
data: data,
};
let response_body = json!(res).to_string();
let resp = http_response::builder()
.status(StatusCode::OK)
.header(http::header::CONTENT_TYPE,mime::APPLICATION_JSON.essence_str())
.body(response_body)
.unwrap();
Ok(resp)
}

// mock for implement stage
#[derive(Debug, Deserialize)]
struct UpdateNoteRequest {
// define fields here
}
33 changes: 33 additions & 0 deletions go_to_rust/easy_note/src/cmd/api/rpc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,40 @@
use volo_http::context::ServerContext;
use volo_http::json::Json;
use async_trait::async_trait;
use crate::cmd::api::rpc;

// mock for implement stage
pub async fn create_user(_cx: &mut ServerContext, _req: CreateUserRequest) -> Result<(), Error> {
todo!("implement it");
}

// mock for implement stage
#[async_trait]
pub async fn delete_note(_identity: &str, _note_id: &str) -> Result<(), String> {
// todo!("implement it");
Ok(())
}

// mock for implement stage
pub fn init() {
// Initialize user and note service clients
todo!("implement it");
}

// mock for implement stage
pub async fn query_notes(user_id: String, request_data: Json) -> Result<(i32, Vec<Json>), Box<dyn std::error::Error>> {
// todo!("implement it");
Ok((0, vec![]))
}

// mock for implement stage
#[async_trait]
pub async fn update_note(user_identity: &str, req_data: &UpdateNoteRequest) -> Result<(), String> {
todo!("implement it");
}

// mock for implement stage
pub async fn create_note(user_identity: &str, data: NoteData) -> Result<(), String> {
// Implement note creation logic
Ok(())
}
10 changes: 10 additions & 0 deletions go_to_rust/easy_note/src/pkg/consts/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
use std::sync::Arc;

// mock for implement stage
pub const API_SERVICE_NAME: &str = "api-service";

// mock for implement stage
pub const EXPORT_ENDPOINT: &str = "http://localhost:4317";

// mock for implement stage
pub static IDENTITY_KEY: Arc<str> = Arc::from("identity_key");

// mock for implement stage
pub static NOTES: &str = "notes";

// mock for implement stage
pub static TOTAL: &str = "total";
20 changes: 20 additions & 0 deletions go_to_rust/easy_note/src/pkg/errno/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
use std::sync::Arc;

use serde::{Deserialize, Serialize};

// mock for implement stage
#[derive(Default, Serialize, Deserialize)]
pub struct ErrNo {
pub err_code: i64,
pub err_msg: String,
}


// mock for implement stage
pub fn convert_err(_err: impl Into<ErrNo>) -> ErrNo {
// todo!("implement it");
ErrNo::default()
}

// mock for implement stage
pub static SUCCESS: Arc<str> = Arc::from("Success");

// mock for implement stage
pub static SERVICE_ERR: &'static str = "Service error";
Loading