iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0
Software Development

Rust 學得動嗎系列 第 15

[Day 15] Rust 在 Web 開發中的應用

  • 分享至 

  • xImage
  •  

今天,我們來聊聊 Rust 在 Web 開發領域的應用,現在很多的職缺都是backend而工作內容則是在寫API,所以我們來看一下兩個流行的 Web 框架:Actix 和 Rocket。這些框架可以讓 Rust 構建高效能、安全的 api server。

1. Actix Web 框架

Actix Web 是一個強大、實用且速度極快的 Rust Web 框架。它建立在 actor 系統之上,提供了出色的效能和靈活性。

基本的 Actix Web 應用程式

Cargo.toml

[dependencies]
actix-web = "4"
use actix_web::{get, web, App, HttpServer, Responder};

#[get("/")]
async fn hello() -> impl Responder {
    "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
}

https://ithelp.ithome.com.tw/upload/images/20240929/201403582HX8rMagHj.png

處理 JSON 資料

use actix_web::{post, web, App, HttpServer, Responder};
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize)]
struct Info {
    name: String,
    age: u32,
}

#[post("/echo")]
async fn echo(info: web::Json<Info>) -> impl Responder {
    web::Json(info.0)
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(echo)
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

https://ithelp.ithome.com.tw/upload/images/20240929/20140358DHmWvOge1T.png

2. Rocket 框架

Rocket 是另一個受歡迎的 Rust Web 框架,以其簡潔的 API 和強大的功能而聞名。

基本的 Rocket 應用程式

Cargo.toml

[dependencies.rocket]
version = "0.5.1"
features = ["json"]
#[macro_use] extern crate rocket;

#[get("/")]
fn index() -> &'static str {
    "Hello, Rocket!"
}

#[launch]
fn rocket() -> _ {
    rocket::build().mount("/", routes![index])
}

https://ithelp.ithome.com.tw/upload/images/20240929/2014035893oxw7VnlS.png

處理查詢參數

use rocket::serde::Serialize;
use rocket::serde::json::Json;

#[derive(Serialize)]
struct User {
    name: String,
    age: u8,
}

#[get("/user?<name>&<age>")]
fn user(name: &str, age: u8) -> Json<User> {
    Json(User {
        name: name.to_string(),
        age,
    })
}

#[launch]
fn rocket() -> _ {
    rocket::build().mount("/", routes![user])
}

https://ithelp.ithome.com.tw/upload/images/20240929/201403581VoObT9as3.png

3. RESTful API 設計

無論使用哪個框架,設計 RESTful API 的原則都是相似的。以下是一個使用 Actix Web 的簡單 CRUD API 示例:

use actix_web::{web, App, HttpServer, Responder, HttpResponse};
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize)]
struct Task {
    id: Option<u32>,
    title: String,
    completed: bool,
}

// 模擬資料庫操作
async fn create_task(task: web::Json<Task>) -> impl Responder {
    // 建立任務邏輯
    HttpResponse::Created().json(task.0)
}

async fn get_task(id: web::Path<u32>) -> impl Responder {
    // Get任務邏輯
    HttpResponse::Ok().json(Task {
        id: Some(id.into_inner()),
        title: "示例任務".to_string(),
        completed: false,
    })
}

async fn update_task(id: web::Path<u32>, task: web::Json<Task>) -> impl Responder {
    // Update任務邏輯
    HttpResponse::Ok().json(task.0)
}

async fn delete_task(id: web::Path<u32>) -> impl Responder {
    // delete任務邏輯
    HttpResponse::NoContent().finish()
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/tasks", web::post().to(create_task))
            .route("/tasks/{id}", web::get().to(get_task))
            .route("/tasks/{id}", web::put().to(update_task))
            .route("/tasks/{id}", web::delete().to(delete_task))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

https://ithelp.ithome.com.tw/upload/images/20240929/20140358YPf47Gh0ng.pnghttps://ithelp.ithome.com.tw/upload/images/20240929/20140358jApYhVQz8X.pnghttps://ithelp.ithome.com.tw/upload/images/20240929/20140358R5112pXgx0.pnghttps://ithelp.ithome.com.tw/upload/images/20240929/20140358UPt3ZL5SGo.png

4. 非同步資料庫操作

在 Web 應用程式中,非同步資料庫操作是關鍵。以下是使用 SQLx 進行非同步 PostgreSQL 操作的示例:

use actix_web::{web, App, HttpServer, Responder};
use sqlx::PgPool;

async fn get_users(db: web::Data<PgPool>) -> impl Responder {
    let users = sqlx::query!("SELECT * FROM users")
        .fetch_all(db.get_ref())
        .await
        .unwrap();

    web::Json(users)
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let pool = PgPool::connect("postgres://username:password@localhost/database")
        .await
        .expect("無法連接到資料庫");

    HttpServer::new(move || {
        App::new()
            .app_data(web::Data::new(pool.clone()))
            .route("/users", web::get().to(get_users))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

5. 中間件和錯誤處理

Web 框架通常提供中間件功能來處理橫切關注點,如日誌記錄、認證等。以下是 Actix Web 中使用中間件的範例:

use actix_web::{web, App, HttpServer, Responder, HttpResponse};
use actix_web::middleware::Logger;

async fn index() -> impl Responder {
    HttpResponse::Ok().body("Hello, World!")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    env_logger::init();

    HttpServer::new(|| {
        App::new()
            .wrap(Logger::default())
            .route("/", web::get().to(index))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

結論

Rust 的 Web 開發生態系統正在快速成長,提供了高效能、類型安全和優秀的開發體驗。無論是選擇 Actix Web 還是 Rocket,都能夠構建出安全、高效的 Web 應用程式,缺點的話應該就是開發的時間會比其他語言框架還要長,而且相關的工程師難找。


上一篇
[Day 14] 如何在Rust 中如何應用常見的軟體設計模式
下一篇
[Day 16] Rust 在系統程式設計中的應用
系列文
Rust 學得動嗎22
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言