Actix-webRust Web框架入門教程

文章目錄

    • 引言
    • Actix-web是什么?
    • 準備工作
    • 你的第一個Actix-web應用
    • 理解代碼結構
    • 處理請求和響應
      • 接收請求數據
      • 返回響應
    • 中間件 - 增強你的應用
    • 狀態管理和依賴注入
    • 實用示例:構建RESTful API
    • 測試你的Actix-web應用
    • 部署Actix-web應用
    • 結語
    • 額外資源

引言

嘿,各位開發者們!今天我要和大家分享一個在Rust生態系統中備受矚目的Web框架——Actix-web。作為Rust世界中最受歡迎的Web框架之一,Actix-web以其驚人的性能和友好的API設計贏得了眾多開發者的青睞。無論你是Rust新手還是老手,這篇教程都將幫助你快速上手這個強大的工具!

我第一次接觸Actix-web時簡直被它的速度震驚了(真的超級快!!!)。如果你正在尋找一個高性能、類型安全且易于使用的Web框架,那么Actix-web絕對值得你花時間學習。

Actix-web是什么?

Actix-web是一個用Rust編寫的高性能Web框架,它建立在actor系統Actix的基礎上(雖然現在已經可以獨立使用)。它提供了創建HTTP服務器和客戶端的工具,支持WebSockets、HTTP/2等現代Web技術。

與其他Web框架相比,Actix-web的主要優勢在于:

  • 極致性能 - 在多項基準測試中,它經常位居前列(有時甚至超過Go和Node.js框架)
  • 類型安全 - 利用Rust的類型系統,避免常見錯誤
  • 異步支持 - 完全擁抱Rust的異步編程模型
  • 靈活性 - 從簡單API到復雜應用,都能勝任

準備工作

在開始之前,你需要準備好Rust開發環境。如果你還沒有安裝Rust,可以通過rustup來安裝:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

確保你的Rust是最新版本:

rustup update

接下來,創建一個新的Rust項目:

cargo new actix_demo
cd actix_demo

然后,在Cargo.toml文件中添加Actix-web依賴:

[dependencies]
actix-web = "4.3.1"

你的第一個Actix-web應用

讓我們開始創建一個簡單的"Hello World"應用。打開src/main.rs文件,并替換為以下內容:

use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder};#[get("/")]
async fn hello() -> impl Responder {HttpResponse::Ok().body("Hello, Actix-web!")
}#[post("/echo")]
async fn echo(req_body: String) -> impl Responder {HttpResponse::Ok().body(req_body)
}async fn manual_hello() -> impl Responder {HttpResponse::Ok().body("Hey there!")
}#[actix_web::main]
async fn main() -> std::io::Result<()> {HttpServer::new(|| {App::new().service(hello).service(echo).route("/hey", web::get().to(manual_hello))}).bind(("127.0.0.1", 8080))?.run().await
}

運行這個程序:

cargo run

現在你可以訪問 http://localhost:8080/ 看到"Hello, Actix-web!"的響應。也可以通過POST請求發送數據到 http://localhost:8080/echo 端點,或者訪問 http://localhost:8080/hey 查看另一個響應。

理解代碼結構

讓我們分解上面的代碼,以便理解Actix-web的核心概念:

  1. 路由處理函數:在Actix-web中,每個路由對應一個處理函數,如上例中的helloechomanual_hello。這些函數必須是異步的,并且返回實現了Responder特質的類型。

  2. 宏注解#[get("/")]#[post("/echo")]是路由宏,它們簡化了路由定義。也可以通過.route()方法手動定義路由,就像/hey路由那樣。

  3. HttpServer和AppHttpServer負責處理HTTP請求,而App是應用程序的主體,它包含了所有的路由和中間件配置。

  4. 綁定和運行:使用.bind()方法指定服務器監聽的地址和端口,然后調用.run().await啟動服務器。

處理請求和響應

在Web開發中,處理請求和生成響應是最基本的任務。Actix-web提供了多種方式來處理這些操作。

接收請求數據

Actix-web支持多種方式獲取請求數據:

  1. 路徑參數
#[get("/users/{id}")]
async fn get_user(path: web::Path<(u32,)>) -> impl Responder {let user_id = path.into_inner().0;HttpResponse::Ok().body(format!("User ID: {}", user_id))
}
  1. 查詢參數
#[derive(Deserialize)]
struct Info {name: String,age: u32,
}#[get("/info")]
async fn info(query: web::Query<Info>) -> impl Responder {format!("Welcome {}! You are {} years old.", query.name, query.age)
}
  1. JSON請求體
#[derive(Deserialize)]
struct User {name: String,email: String,
}#[post("/users")]
async fn create_user(user: web::Json<User>) -> impl Responder {HttpResponse::Created().json(user.into_inner())
}

返回響應

Actix-web提供了多種方式來構建響應:

  1. 簡單文本響應
HttpResponse::Ok().body("Hello world!")
  1. JSON響應
#[derive(Serialize)]
struct Response {message: String,status: String,
}async fn json_response() -> impl Responder {let response = Response {message: "Success".to_string(),status: "OK".to_string(),};web::Json(response)
}
  1. 重定向
async fn redirect() -> impl Responder {HttpResponse::Found().append_header(("Location", "/login")).finish()
}

中間件 - 增強你的應用

中間件允許你在請求處理的前后添加額外的邏輯。Actix-web提供了許多內置的中間件,如日志記錄、壓縮、CORS支持等。你也可以創建自定義中間件。

以下是如何添加日志中間件的示例:

use actix_web::middleware::Logger;#[actix_web::main]
async fn main() -> std::io::Result<()> {std::env::set_var("RUST_LOG", "actix_web=info");env_logger::init();HttpServer::new(|| {App::new().wrap(Logger::default()).service(hello)}).bind(("127.0.0.1", 8080))?.run().await
}

這會記錄所有傳入的請求,包括路徑、狀態碼和處理時間。

狀態管理和依賴注入

在Web應用中,你經常需要在不同的請求處理程序之間共享狀態(如數據庫連接)。Actix-web提供了一種類型安全的方式來實現這一點:

use std::sync::Mutex;struct AppState {counter: Mutex<i32>,
}#[get("/count")]
async fn count(data: web::Data<AppState>) -> String {let mut counter = data.counter.lock().unwrap();*counter += 1;format!("Request number: {}", counter)
}#[actix_web::main]
async fn main() -> std::io::Result<()> {let app_state = web::Data::new(AppState {counter: Mutex::new(0),});HttpServer::new(move || {App::new().app_data(app_state.clone()).service(count)}).bind(("127.0.0.1", 8080))?.run().await
}

這個例子創建了一個簡單的計數器,每次訪問/count路徑時增加計數。

實用示例:構建RESTful API

讓我們構建一個簡單的待辦事項API,它支持創建、讀取、更新和刪除操作(CRUD):

use actix_web::{web, App, HttpResponse, HttpServer, Responder};
use serde::{Deserialize, Serialize};
use std::sync::Mutex;#[derive(Debug, Serialize, Deserialize, Clone)]
struct Task {id: Option<u32>,title: String,completed: bool,
}struct AppState {tasks: Mutex<Vec<Task>>,counter: Mutex<u32>,
}async fn get_tasks(data: web::Data<AppState>) -> impl Responder {let tasks = data.tasks.lock().unwrap();HttpResponse::Ok().json(&*tasks)
}async fn get_task_by_id(path: web::Path<u32>, data: web::Data<AppState>) -> impl Responder {let task_id = path.into_inner();let tasks = data.tasks.lock().unwrap();if let Some(task) = tasks.iter().find(|t| t.id == Some(task_id)) {HttpResponse::Ok().json(task)} else {HttpResponse::NotFound().body("Task not found")}
}async fn create_task(task: web::Json<Task>, data: web::Data<AppState>) -> impl Responder {let mut tasks = data.tasks.lock().unwrap();let mut counter = data.counter.lock().unwrap();let mut new_task = task.into_inner();*counter += 1;new_task.id = Some(*counter);tasks.push(new_task.clone());HttpResponse::Created().json(new_task)
}async fn update_task(path: web::Path<u32>, task: web::Json<Task>, data: web::Data<AppState>) -> impl Responder {let task_id = path.into_inner();let mut tasks = data.tasks.lock().unwrap();if let Some(pos) = tasks.iter().position(|t| t.id == Some(task_id)) {let mut updated_task = task.into_inner();updated_task.id = Some(task_id);tasks[pos] = updated_task.clone();HttpResponse::Ok().json(updated_task)} else {HttpResponse::NotFound().body("Task not found")}
}async fn delete_task(path: web::Path<u32>, data: web::Data<AppState>) -> impl Responder {let task_id = path.into_inner();let mut tasks = data.tasks.lock().unwrap();if let Some(pos) = tasks.iter().position(|t| t.id == Some(task_id)) {tasks.remove(pos);HttpResponse::Ok().body("Task deleted")} else {HttpResponse::NotFound().body("Task not found")}
}#[actix_web::main]
async fn main() -> std::io::Result<()> {let app_state = web::Data::new(AppState {tasks: Mutex::new(Vec::new()),counter: Mutex::new(0),});HttpServer::new(move || {App::new().app_data(app_state.clone()).route("/tasks", web::get().to(get_tasks)).route("/tasks", web::post().to(create_task)).route("/tasks/{id}", web::get().to(get_task_by_id)).route("/tasks/{id}", web::put().to(update_task)).route("/tasks/{id}", web::delete().to(delete_task))}).bind(("127.0.0.1", 8080))?.run().await
}

這個例子實現了一個完整的RESTful API,支持以下操作:

  • GET /tasks - 獲取所有任務
  • POST /tasks - 創建新任務
  • GET /tasks/{id} - 獲取特定任務
  • PUT /tasks/{id} - 更新特定任務
  • DELETE /tasks/{id} - 刪除特定任務

測試你的Actix-web應用

Actix-web提供了測試工具,讓你可以方便地測試你的應用:

#[cfg(test)]
mod tests {use super::*;use actix_web::{test, App};#[actix_web::test]async fn test_hello_endpoint() {let app = test::init_service(App::new().service(hello)).await;let req = test::TestRequest::get().uri("/").to_request();let resp = test::call_service(&app, req).await;assert!(resp.status().is_success());let body = test::read_body(resp).await;assert_eq!(body, "Hello, Actix-web!");}
}

這個測試創建了一個測試服務,發送GET請求到"/"路徑,然后驗證響應狀態和內容。

部署Actix-web應用

當你準備部署你的應用時,記住以下幾點:

  1. 使用--release標志進行編譯,以獲得最佳性能:
cargo build --release
  1. 考慮使用反向代理(如Nginx)來處理SSL、負載均衡等:
server {listen 80;server_name example.com;location / {proxy_pass http://localhost:8080;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection 'upgrade';proxy_set_header Host $host;proxy_cache_bypass $http_upgrade;}
}
  1. 為生產環境配置日志和監控。

結語

Actix-web是一個功能強大且高性能的Web框架,非常適合構建從簡單API到復雜Web應用的各種項目。它的類型安全和并發模型使得開發安全可靠的Web服務變得簡單。

雖然學習曲線可能比一些其他語言的Web框架稍陡(主要是因為Rust本身),但投入的時間絕對值得。一旦你習慣了Actix-web的開發模式,你會發現它不僅高效而且非常愉快!

希望這篇教程能幫助你開始使用Actix-web!記住,最好的學習方式是實踐,所以趕快動手嘗試吧。(相信我,你會愛上它的!)

額外資源

  • Actix-web官方文檔
  • Actix-web GitHub倉庫
  • Rust編程語言官方文檔

祝你編碼愉快!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/922449.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/922449.shtml
英文地址,請注明出處:http://en.pswp.cn/news/922449.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

若依框架前端通過 nginx docker 鏡像本地運行

1. 前言 項目運行過程圖&#xff1a;對于前端項目通過命令 npm run build 打包后&#xff0c;無法直接運行。存在如下錯誤&#xff1a;可以通過配置 nginx 服務器運行前端項目解決如上問題。 2. Nginx 運行 采用 docker 鏡像的方式運行&#xff0c;docker-compose.yml 文件內容…

淺聊一下HTTP協議

在日常上網瀏覽網頁、刷視頻時&#xff0c;背后都離不開 HTTP 協議的支持。作為 Web 世界的 “交通規則”&#xff0c;它負責服務器和客戶端瀏覽器之間的數據傳輸。這篇文章就帶大家全面了解 HTTP 協議&#xff0c;從基本概念到通信細節&#xff0c;再到安全相關的 HTTPS&#…

機器人控制器開發(定位——cartographer ros2 使用2)

文章總覽 1 純定位模式 當完成建圖后&#xff0c;會生成pbstream格式的地圖文件 配置純定位模式的lua腳本 backpack_2d_localization.lua include "backpack_2d.lua"TRAJECTORY_BUILDER.pure_localization_trimmer {max_submaps_to_keep 3, } POSE_GRAPH.optimi…

《大數據之路1》筆記3:數據管理

一 元數據 1.1 元數據概述 定義&#xff1a; 元數據是關于數據的數據&#xff0c;元數據打通了源數據、數據倉庫、數據應用&#xff0c;記錄了數據從生產到消費的全部過程。元數據主要記錄數據倉庫中模型的定義、各層級間的映射關系、監控數據倉庫的數據狀態和ETL的任務運行狀態…

排序實現java

排序算法概述Java中實現排序可以通過多種方式&#xff0c;包括內置方法、自定義算法或使用第三方庫。常見的排序算法有冒泡排序、選擇排序、插入排序、快速排序、歸并排序等。使用Arrays.sort()方法對于數組排序&#xff0c;Java提供了Arrays.sort()方法&#xff0c;支持對基本…

51c大模型~合集182

我自己的原文哦~ https://blog.51cto.com/whaosoft/14174587 #LaV-CoT 超越GPT-4o&#xff0c;螞蟻集團與南洋理工大學提出&#xff1a;首個語言感知的視覺思維鏈 隨著大型視覺語言模型&#xff08;VLM&#xff09;的飛速發展&#xff0c;它們在處理復雜的視…

C++ STL之deque的使用和模擬實現

目錄 deque 核心本質與定位 與stack和queue的關系: deque的使用 deque的底層實現 deque的原理介紹 deque的缺陷 總結: deque deque文檔 : deque 翻譯: 雙端隊列 deque&#xff08;通常發音類似“deck”&#xff09;是“double-ended queue”&#xff08;雙端隊列&…

布草洗滌廠設備租賃押金原路退回系統—東方仙盟

設備租賃狀態設備管理添加設備設備收押金設備退押金在布草洗滌行業的運營版圖中&#xff0c;設備租賃是連接廠商與客戶的重要紐帶&#xff0c;而押金的收取與退還則是這一環節中關乎信任與效率的關鍵節點。未來之窗布草洗滌廠深諳此道&#xff0c;專為設備租賃業務打造的 “押金…

換源rocklinux和centos

一、Rockylinux換源&#xff0c;國外的源換成國內的源#nmcli connection modify ens33 ipv4.addresses 192.168.121.11 ipv4.gateway 192.168.121.2 ipv4.method manual ipv4.dns 114.114.114.114 connection.autoconnect yes修改地址#systemctl stop firewalld#systemctl diab…

第一部分:服務器硬件配置

目錄1.1 服務器上架與連線1.2 啟用CPU虛擬化功能&#xff08;BIOS設置&#xff09;1.3 配置RAID存儲步驟1&#xff1a;進入RAID配置界面步驟2&#xff1a;確認RAID控制器信息步驟3&#xff1a;創建系統RAID&#xff08;用于安裝ESXi&#xff09;步驟4&#xff1a;創建數據RAID&…

手搓一個 DELL EMC Unity存儲系統健康檢查清單

寫在前面對于DELL EMC存儲系統Unity的一些深度的健康檢查通過Web的Unisphere圖形化界面是做不到的&#xff0c;圖形化界面只能看到是否有告警&#xff0c;物理的東西是否有問題的&#xff0c;邏輯的Pool和LUN等是否ready&#xff0c;再深入的潛在的問題是查不到的。另外&#x…

【數據結構】二叉樹的概念

01 概念定義&#xff1a;二叉樹既然叫二叉樹&#xff0c;顧名思義即度最大為2的樹稱為二叉樹。 它的度可以為 1 也可以為 0&#xff0c;但是度最大為 2 。 一顆二叉樹是節點的一個有限集合&#xff0c;該集合&#xff1a;① 由一個根節點加上兩棵被稱為左子樹和右子樹的二叉樹組…

【RK3576】【Android14】如何在Android14下單獨編譯kernel-6.1?

單獨編譯kernel依賴如下幾個源碼&#xff1a;【交叉編譯工具鏈】prebuilts/clang/host/linux-x86/clang-r487747c【內核源碼】kernel-6.1為什么Android下編譯內核使用clang作為交叉編譯工具鏈而不是GCC&#xff1f;Android 14 選擇使用預置的 Clang 工具鏈&#xff08;如 clang…

什么是Redis的Pipeline

介紹Redis的Pipeline是一種網絡優化技術&#xff0c;在沒有Pipeline的時候&#xff0c;客戶端往redis發送請求&#xff0c;客戶端需要等到redis響應之后才能發送下一個請求。而Pipeline&#xff0c;使redis可以一次性接收多個請求。減少了通信次數&#xff0c;顯著的提高了性能…

【ElementUI el-table跨頁勾選】

一、el-table需加上refs和 row-key屬性 二、type"selection"勾選框 需加上 reserve-selection儲備選擇屬性 三、在分頁請求數據時&#xff0c;觸發 setSelected()方法 四、在 selection-change變化時保存 selectedRows <el-table ref"tables" :data&quo…

論文閱讀/博弈論/拍賣:《Truthful Auction for Cooperative Communications》

摘要&#xff1a;一方面&#xff0c;協作通信由于其在提升無線網絡容量方面的巨大潛力而日益受到關注。另一方面&#xff0c;協作通信技術的實際應用卻很少見&#xff0c;即使在一些對帶寬需求極高的應用場景中&#xff0c;系統設計者也并未采用協作通信技術來開發創新的網絡解…

系統軟中間件:連接軟件與硬件的橋梁

理解“系統軟中間件”這個術語很重要&#xff0c;它實際上是兩個緊密相關但又不同的概念的組合&#xff1a; 系統軟件中間件 嚴格來說&#xff0c;“系統軟中間件”不是一個標準的獨立術語。它通常指的是屬于系統軟件范疇的中間件&#xff0c;或者理解為作為系統軟件重要組成部…

音視頻學習(六十四):avc1 hvc1和hev1

基礎概念縮寫編碼標準FourCC說明AVC/H.264Advanced Video Codingavc1最常用的 H.264 編碼標識符&#xff0c;兼容 MP4/MOV/FMP4 等容器。HEVC/H.265High Efficiency Video Codinghvc1HEVC 視頻流在 MP4/FMP4 中常用標識符&#xff0c;要求存儲 NALU 的 VPS/SPS/PPS&#xff08;…

【WIT】編程百問一

01 什么時postman&#xff1f; Postman 是一款專門用于幫助開發人員處理 API 的工具&#xff0c;它的作用主要有以下幾個方面&#xff1a; 方便調試 API&#xff1a;就像你打電話給別人要先撥對號碼一樣&#xff0c;開發人員要讓不同的軟件系統之間通過 API 進行通信&#xff…

RAG 從入門到放棄?丐版 demo 實戰筆記(go+python)

背景 我當前有一個業務系統&#xff0c;希望能添加一個機器人助手。直接使用大模型&#xff0c;由于缺少相關的業務數據&#xff0c;效果并不理想&#xff0c;了解一下 RAG。 什么是 RAG RAG(Retrieval Augmented Generation)&#xff0c;搜索引擎 大模型。 簡單來說就是從…