Skip to content

Acitx-Web

一款 Rust Web 框架,使用 Rust 编写,性能高,使用简单,支持路由,支持中间件,支持异步编程,支持 WebSocket,支持 WebRTC,支持 WebGL,支持 WebGPU,支持 WebAssembly,支持 WebCrypto,支持 WebStorage,支持 WebAudio,支持 WebVTT,支持 WebIDL

快速开始

  1. 创建一个新项目,
rust
cargo init example-api
  1. 安装 actix-web 依赖
bash
cargo add actix-web
  1. 在 main.rs 编写代码
rust
use actix_web::{web, App, HttpServer, Responder};

#[get("/")]
async fn index() -> impl Responder {
    "Hello world!"
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new().service(
            web::scope("/")
                .route("/", web::get().to(index)),
        )
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

提取器

Actix Web 提供了类型安全的请求提取器。例如,使用 JSON 提取器:cargo add serde -F derive

rust
use actix_web::web;
use serde::Deserialize;

#[derive(Deserialize)]
struct Info {
    username: String,
}
// 获取post body json
#[post("/submit")]
async fn submit(info: web::Json<Info>) -> String {
    format!("Welcome {}!", info.username)
}

// 获取路径参数
#[get("/users/{username}")]
async fn index(info: web::Path<Info>) -> String {
    format!("Welcome {}!", info.username)
}

// 获取url query参数
#[get("/")]
async fn index(info: web::Query<Info>) -> String {
    format!("Welcome {}!", info.username)
}

// 获取form表单
#[post("/")]
async fn index(form: web::Form<Info>) -> actix_web::Result<String> {
    Ok(format!("Welcome {}!", form.username))
}

连接数据库

连接Sqlite

  1. 安装数据库依赖
bash
cargo add r2d2
cargo add r2d2_sqlite
  1. 连接数据库
rust

// 初始化数据库连接池
fn initialize_db_pool() -> DbPool {
    let manager = r2d2::ConnectionManager::<SqliteConnection>::new("db/db.db");
    r2d2::Pool::builder()
        .build(manager)
        .expect("database URL should be valid path to SQLite DB file")
}

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

    let pool = initialize_db_pool();
       
    HttpServer::new(move || {
        App::new()
            .app_data(web::Data::new(pool.clone()))
            // .service(list) 
            // 其他路由代码
            
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

接口中使用数据库

创建几个.rs文件

rust
// 用于存放表结构

use diesel::table;
table! {
  user_table (id) {
      id -> Text,
      name -> Text,
  }
}
rust
// 定义数据结构
use serde::{Deserialize, Serialize};
use crate::schema::user_table;
use diesel::{prelude::*};

#[derive(Debug, Clone, Serialize, Deserialize, Queryable, Insertable)]
#[diesel(table_name = user_table)]  
pub struct UserInfo {
    pub id: String,
    pub name: String,
}
rust
use diesel::prelude::*;
use crate::{models};
type DbError = Box<dyn std::error::Error + Send + Sync>;

// 数据库操作
pub fn get_user_list(
  conn: &mut SqliteConnection,
) -> Result<Option<Vec<models::FontManage>>, DbError> {
  use crate::schema::::user_table::*; 

  let data = user_table 
          .limit(10) // 查询10条数据
          .load::<models::FontManage>(conn)
          .optional()?;

  Ok(data)
}
rust
use diesel::{prelude::*, r2d2};
use actix_web::{error, get, middleware, post, web, App, HttpRequest, HttpResponse, HttpServer, Responder, Result};

// 引入模块
mod models;
mod actions;
mod schema;
use schema::user_table::dsl::*; // 引入表字段

type DbPool = r2d2::Pool<r2d2::ConnectionManager<SqliteConnection>>;

#[get("/list")]
async fn list(
    // 这里就是数据库连接池
    pool: web::Data<DbPool>,  
) -> Result<impl Responder> {
    let data = web::block(move || {
        let mut conn = pool.get()?;
        // 调用数据库操作
        actions::get_user_list(&mut conn, params.into_inner()) 
    })
    .await?
    .map_err(error::ErrorInternalServerError)?;
    HttpResponse::Ok().body("Hello world!")
}

中间件

日志中间件

rust
use actix_web::{
    middleware::Logger, 
    App
};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); 
    // 输出日志
    log::info!("starting HTTP server at http://localhost:8080"); 

    HttpServer::new(move || {
        App::new()
            .wrap(Logger::default()) 
            // 其余代码
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

静态文件服务

安装依赖

rust
cargo add actix-files

使用

rust
use actix_files as fs;
use actix_web::{App, HttpServer};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new().service(
            fs::Files::new("/static", ".")
                .use_last_modified(true),
        )
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

个人收集整理, MIT License