请求处理

本文将介绍 Silent 框架中的请求处理机制,包括如何获取和解析各种类型的请求数据。

请求体解析

Silent 框架支持多种请求体格式的自动解析:

JSON 请求体

use serde::Deserialize;
use silent::prelude::*;

#[derive(Deserialize)]
struct CreateUser {
    name: String,
    email: String,
}

#[handler]
async fn create_user(body: Json<CreateUser>) -> Result<String> {
    Ok(format!("Created user: {}", body.name))
}

表单数据

use serde::Deserialize;

#[derive(Deserialize)]
struct LoginForm {
    username: String,
    password: String,
}

#[handler]
async fn login(form: Form<LoginForm>) -> Result<String> {
    Ok(format!("Login attempt for user: {}", form.username))
}

文件上传

#[handler]
async fn upload(mut multipart: Multipart) -> Result<String> {
    while let Some(field) = multipart.next_field().await? {
        let name = field.name().unwrap().to_string();
        let filename = field.filename().unwrap().to_string();
        let content_type = field.content_type().unwrap().to_string();
        let data = field.bytes().await?;
        
        // 处理上传的文件
    }
    Ok("Files uploaded successfully".to_string())
}

查询参数

基本查询参数

#[handler]
async fn search(query: Query<HashMap<String, String>>) -> String {
    format!("Search query: {:?}", query)
}

结构化查询参数

#[derive(Deserialize)]
struct SearchParams {
    keyword: String,
    page: Option<u32>,
    limit: Option<u32>,
}

#[handler]
async fn advanced_search(query: Query<SearchParams>) -> String {
    format!("Search for: {} on page {}", query.keyword, query.page.unwrap_or(1))
}

路径参数

基本路径参数

#[handler]
async fn get_user(params: Path<HashMap<String, String>>) -> String {
    format!("User ID: {}", params.get("id").unwrap())
}

let route = Route::new("users/:id").get(get_user);

结构化路径参数

#[derive(Deserialize)]
struct UserParams {
    id: String,
    action: String,
}

#[handler]
async fn user_action(params: Path<UserParams>) -> String {
    format!("User {} performing {}", params.id, params.action)
}

let route = Route::new("users/:id/:action").get(user_action);

请求头

读取请求头

#[handler]
async fn auth(headers: HeaderMap) -> Result<()> {
    if let Some(token) = headers.get("Authorization") {
        // 验证 token
        Ok(())
    } else {
        Err(Error::new("Missing authorization token"))
    }
}

自定义请求头

#[derive(Deserialize)]
struct ApiVersion {
    version: String,
}

#[handler]
async fn api_handler(version: Header<ApiVersion>) -> String {
    format!("API Version: {}", version.version)
}

最佳实践

  1. 使用强类型的请求模型,利用 Serde 的序列化功能

  2. 为可选参数提供合理的默认值

  3. 对用户输入进行适当的验证和清理

  4. 使用适当的错误处理机制

  5. 合理组织请求处理逻辑,保持代码清晰

完整示例

这是一个综合示例,展示了如何处理不同类型的请求数据:

use serde::Deserialize;
use silent::prelude::*;

#[derive(Deserialize)]
struct CreatePost {
    title: String,
    content: String,
    tags: Vec<String>,
}

#[derive(Deserialize)]
struct PostQuery {
    category: Option<String>,
    page: Option<u32>,
    limit: Option<u32>,
}

#[handler]
async fn create_post(
    headers: HeaderMap,
    body: Json<CreatePost>,
) -> Result<String> {
    // 验证认证信息
    let token = headers.get("Authorization")
        .ok_or_else(|| Error::new("Missing authorization"))?;
    
    // 处理请求数据
    Ok(format!("Created post: {}", body.title))
}

#[handler]
async fn list_posts(
    query: Query<PostQuery>,
) -> String {
    let page = query.page.unwrap_or(1);
    let limit = query.limit.unwrap_or(10);
    
    format!("Listing posts on page {} with limit {}", page, limit)
}

这个示例展示了如何处理带有认证头的 JSON 请求体,以及如何处理带有可选参数的查询字符串。代码结构清晰,易于理解和维护。

Last updated

Was this helpful?