当前位置: 首页 > news >正文

基于 Rust 的Actix Web 框架的应用与优化实例

基于 Rust 的Actix Web 框架的应用与优化实例

Actix Web 框架概述

Actix Web 是一个基于 Rust 的高性能、轻量级 Web 框架,构建于 Actix 异步运行时之上。它支持异步编程模型,适合构建高并发、低延迟的 Web 服务和 API。

核心特性

  • 异步支持:基于 async/await 语法,充分利用 Rust 的异步生态。
  • 高性能:底层使用 actor 模型和零成本抽象,性能接近原生代码。
  • 类型安全:通过 Rust 的类型系统确保路由、请求和响应的安全性。
  • 灵活的路由:支持 RESTful 路由、动态路径参数和中间件。
  • WebSocket 支持:内置 WebSocket 协议支持。

基本项目结构

典型的 Actix Web 项目结构如下:

src/
├── main.rs      # 应用入口和路由配置
├── handlers.rs  # 请求处理逻辑
├── models.rs    # 数据模型
└── lib.rs       # 模块定义(可选)

快速入门示例

以下是一个最小化的 Actix Web 应用代码:

use actix_web::{get, App, HttpResponse, HttpServer, Responder};#[get("/")]
async fn hello() -> impl Responder {HttpResponse::Ok().body("Hello, Actix Web!")
}#[actix_web::main]
async fn main() -> std::io::Result<()> {HttpServer::new(|| App::new().service(hello)).bind("127.0.0.1:8080")?.run().await
}

关键组件

  1. 路由与处理函数

    • 使用 #[get]#[post] 等宏定义路由。
    • 处理函数返回 impl Responder,支持多种响应类型(如 HttpResponseString)。
  2. 状态共享
    通过 Data<T> 类型共享全局状态(如数据库连接池):

    App::new().app_data(Data::new(AppState { db: pool }))
    
  3. 中间件
    使用 wrap 添加中间件(如日志、认证):

    App::new().wrap(Logger::default())
    
  4. 错误处理
    自定义错误类型并实现 ResponseError trait:

    impl ResponseError for MyError {fn error_response(&self) -> HttpResponse {HttpResponse::InternalServerError().finish()}
    }
    

安装 Actix Web 依赖 在 Cargo.toml 中添加以下依赖:

[dependencies]
actix-web = "4"

创建基础 HTTP 服务器

use actix_web::{get, App, HttpResponse, HttpServer, Responder};#[get("/")]
async fn hello() -> impl Responder {HttpResponse::Ok().body("Hello world!")
}#[actix_web::main]
async fn main() -> std::io::Result<()> {HttpServer::new(|| App::new().service(hello)).bind(("127.0.0.1", 8080))?.run().await
}

路由处理示例

多路由配置

use actix_web::{web, App, HttpResponse, HttpServer};async fn index() -> HttpResponse {HttpResponse::Ok().body("Index page")
}async fn about() -> HttpResponse {HttpResponse::Ok().body("About page")
}#[actix_web::main]
async fn main() -> std::io::Result<()> {HttpServer::new(|| {App::new().route("/", web::get().to(index)).route("/about", web::get().to(about))}).bind(("127.0.0.1", 8080))?.run().await
}

路径参数提取

use actix_web::{get, web, App, HttpServer};#[get("/users/{user_id}/{friend}")]
async fn user_info(path: web::Path<(u32, String)>) -> String {let (user_id, friend) = path.into_inner();format!("User {}'s friend: {}", user_id, friend)
}

以下是基于Rust的路由处理示例,涵盖不同框架和场景的实用案例。示例分为基础路由、动态参数、中间件、错误处理等类别,代码均以实际可运行为目标。


基础路由(axum框架)

use axum::{Router, routing::get, Json};
use serde_json::json;async fn hello_world() -> Json<serde_json::Value> {Json(json!({ "message": "Hello, world!" }))
}#[tokio::main]
async fn main() {let app = Router::new().route("/", get(hello_world));axum::Server::bind(&"0.0.0.0:3000".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
}

动态路径参数

use axum::{Router, routing::get, extract::Path};async fn user_info(Path(user_id): Path<u32>) -> String {format!("User ID: {}", user_id)
}let app = Router::new().route("/users/:user_id", get(user_info));

查询参数处理

use axum::{Router, routing::get, extract::Query};
use serde::Deserialize;#[derive(Deserialize)]
struct Pagination {page: usize,per_page: usize,
}async fn list_items(Query(pagination): Query<Pagination>) -> String {format!("Page: {}, Per Page: {}", pagination.page, pagination.per_page)
}let app = Router::new().route("/items", get(list_items));

JSON请求体处理

use axum::{Router, routing::post, Json, extract::Extension};
use serde::{Deserialize, Serialize};#[derive(Deserialize)]
struct CreateUser {name: String,
}#[derive(Serialize)]
struct User {id: u64,name: String,
}async fn create_user(Json(input): Json<CreateUser>) -> Json<User> {Json(User { id: 1, name: input.name })
}let app = Router::new().route("/users", post(create_user));


中间件示例(日志记录)

use axum::{Router, routing::get, middleware};
use tower_http::trace::TraceLayer;async fn handler() -> &'static str { "OK" }let app = Router::new().route("/", get(handler)).layer(TraceLayer::new_for_http());

错误处理

use axum::{Router, routing::get, response::IntoResponse, http::StatusCode};async fn fallible_handler() -> Result<String, (StatusCode, &'static str)> {Err((StatusCode::INTERNAL_SERVER_ERROR, "Something went wrong"))
}let app = Router::new().route("/error", get(fallible_handler));

静态文件服务

use axum::{Router, routing::get_service};
use tower_http::services::ServeDir;let app = Router::new().nest_service("/static",get_service(ServeDir::new("./static"))
);

路由嵌套

use axum::{Router, routing::get};async fn api_v1_users() -> &'static str { "v1 users" }
async fn api_v2_users() -> &'static str { "v2 users" }let api_v1 = Router::new().route("/users", get(api_v1_users));
let api_v2 = Router::new().route("/users", get(api_v2_users));
let app = Router::new().nest("/api/v1", api_v1).nest("/api/v2", api_v2);

异步数据库操作

use axum::{Router, routing::get, Extension};
use sqlx::postgres::PgPoolOptions;async fn db_handler(Extension(pool): Extension<sqlx::PgPool>) -> String {let row: (i64,) = sqlx::query_as("SELECT $1").bind(150_i64).fetch_one(&pool).await.unwrap();format!("Result: {}", row.0)
}#[tokio::main]
async fn main() {let pool = PgPoolOptions::new().connect("postgres://user:pass@localhost/db").await.unwrap();let app = Router::new().route("/db", get(db_handler)).layer(Extension(pool));
}

WebSocket路由(axum)

use axum::{Router, routing::get, extract::ws::WebSocketUpgrade};async fn ws_handler(ws: WebSocketUpgrade) -> impl IntoResponse {ws.on_upgrade(|socket| async move {// WebSocket处理逻辑})
}let app = Router::new().route("/ws", get(ws_handler));

JSON 请求与响应

JSON 响应处理

use actix_web::{get, App, HttpServer, Responder};
use serde::Serialize;#[derive(Serialize)]
struct MyObj {name: String,age: u8,
}#[get("/json")]
async fn json_response() -> impl Responder {web::Json(MyObj {name: "Alice".to_string(),age: 30,})
}

JSON 请求处理

use actix_web::{post, web, App, HttpServer, Responder};
use serde::Deserialize;#[derive(Deserialize)]
struct Info {username: String,
}#[post("/submit")]
async fn submit(info: web::Json<Info>) -> impl Responder {format!("Welcome {}!", info.username)
}

以下是基于Rust的JSON请求与响应处理的实用示例集合,涵盖常见场景和库(如serdereqwestactix-web等)。示例按功能分类,每个示例独立可用。


基础序列化与反序列化

use serde::{Deserialize, Serialize};#[derive(Debug, Serialize, Deserialize)]
struct User {id: u32,name: String,
}// 序列化结构体到JSON字符串
let user = User { id: 1, name: "Alice".to_string() };
let json_str = serde_json::to_string(&user).unwrap();
println!("Serialized: {}", json_str); // {"id":1,"name":"Alice"}// 反序列化JSON字符串到结构体
let decoded_user: User = serde_json::from_str(&json_str).unwrap();
println!("Deserialized: {:?}", decoded_user);

使用reqwest发送GET请求

use reqwest::Error;#[tokio::main]
async fn main() -> Result<(), Error> {let response = reqwest::get("https://jsonplaceholder.typicode.com/posts/1").await?.json::<serde_json::Value>().await?;println!("Response: {:?}", response);Ok(())
}


使用reqwest发送POST请求

#[derive(Serialize)]
struct Post {title: String,body: String,userId: u32,
}#[tokio::main]
async fn main() -> Result<(), Error> {let new_post = Post {title: "Test Title".to_string(),body: "Test Body".to_string(),userId: 1,};let client = reqwest::Client::new();let res = client.post("https://jsonplaceholder.typicode.com/posts").json(&new_post).send().await?.json::<serde_json::Value>().await?;println!("Response: {:?}", res);Ok(())
}


使用actix-web处理JSON请求

use actix_web::{web, App, HttpServer, Responder};#[derive(Deserialize)]
struct Info {username: String,
}async fn greet(info: web::Json<Info>) -> impl Responder {format!("Hello {}!", info.username)
}#[actix_web::main]
async fn main() -> std::io::Result<()> {HttpServer::new(|| App::new().route("/greet", web::post().to(greet))).bind("127.0.0.1:8080")?.run().await
}


处理嵌套JSON结构

#[derive(Serialize, Deserialize)]
struct Address {street: String,city: String,
}#[derive(Serialize, Deserialize)]
struct Profile {name: String,age: u8,address: Address,
}let profile = Profile {name: "Bob".to_string(),age: 30,address: Address {street: "Main St".to_string(),city: "Metropolis".to_string(),},
};let json = serde_json::to_string_pretty(&profile).unwrap();
println!("{}", json);


自定义字段名称

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Product {product_id: u32,product_name: String,
}let product = Product {product_id: 101,product_name: "Laptop".to_string(),
};
let json = serde_json::to_string(&product).unwrap(); // {"productId":101,"productName":"Laptop"}


处理可选字段

#[derive(Serialize, Deserialize)]
struct Book {title: String,#[serde(skip_serializing_if = "Option::is_none")]subtitle: Option<String>,
}let book1 = Book { title: "Rust".to_string(), subtitle: None };
let json1 = serde_json::to_string(&book1).unwrap(); // {"title":"Rust"}let book2 = Book { title: "Rust".to_string(), subtitle: Some("Advanced".to_string()) };
let json2 = serde_json::to_string(&book2).unwrap(); // {"title":"Rust","subtitle":"Advanced"}


使用Hyper客户端

use hyper::{Client, Body};
use hyper_tls::HttpsConnector;#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {let https = HttpsConnector::new();let client = Client::builder().build::<_, Body>(https);let uri = "https://jsonplaceholder.typicode.com/todos/1".parse()?;let resp = client.get(uri).await?;let body_bytes = hyper::body::to_bytes(resp.into_body()).await?;let body_str = String::from_utf8(body_bytes.to_vec())?;println!("Response: {}", body_str);Ok(())
}


处理日期时间

use chrono::{DateTime, Utc};#[derive(Serialize, Deserialize)]
struct Event {name: String,#[serde(with = "chrono::serde::ts_seconds")]timestamp: DateTime<Utc>,
}let event = Event {name: "Conference".to_string(),timestamp: Utc::now(),
};
let json = serde_json::to_string(&event).unwrap();


使用warp框架

use warp::Filter;#[derive(Serialize, Deserialize)]
struct Message {text: String,
}let hello = warp::path("hello").and(warp::post())
http://www.dtcms.com/a/269974.html

相关文章:

  • C++ 选择排序、冒泡排序、插入排序
  • mac安装docker
  • APISEC安全平台
  • 嵌入式学习笔记-MCU阶段-DAY01
  • WPF之命令
  • 使用elasticdump高效备份与恢复Elasticsearch数据
  • WebSocket详细教程 - SpringBoot实战指南
  • EPLAN 电气制图(四):EPLAN 总电源电路设计知识详解
  • mit6.5840-lab3-3D-SnapShot-25Summer
  • 常见前端开发问题的解决办法
  • 深度学习——神经网络1
  • JK触发器Multisim电路仿真——硬件工程师笔记
  • HMI安全设计规范:ISO 26262合规的功能安全实现路径
  • python2.7/lib-dynload/_ssl.so: undefined symbol: sk_pop_free
  • 查询依赖冲突工具maven Helper
  • 常见的网络攻击方式及防御措施
  • 人工智能与人工智障———仙盟创梦IDE
  • Go HTTP 调用(上)
  • LeetCode 1248.统计优美子数组
  • cocos2dx3.x项目升级到xcode15以上的iconv与duplicate symbols报错问题
  • 云原生时代的日志管理:ELK、Loki、Fluentd 如何选型?
  • C++11 算法详解:std::copy_if 与 std::copy_n
  • UVC(USB Video Class,USB 视频类)协议
  • 代码详细注释:ARM-Linux字符设备驱动开发案例:LCD汉字输出改进建议开发板断电重启还能显示汉字,显示汉字位置自定义
  • 高版本的MacOS如何降级?
  • 数据库|达梦DM数据库配置实例步骤
  • npm 包 scheduler 介绍
  • 黑马点评系列问题之P37商户点评缓存作业,用了string和list两种方法,可以直接复制粘贴
  • K8s-配置管理
  • 【web安全】SQLMap 参数深度解析:--risk 与 --level 详解