请求处理
本文将介绍 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)
}最佳实践
使用强类型的请求模型,利用 Serde 的序列化功能
为可选参数提供合理的默认值
对用户输入进行适当的验证和清理
使用适当的错误处理机制
合理组织请求处理逻辑,保持代码清晰
完整示例
这是一个综合示例,展示了如何处理不同类型的请求数据:
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?