Acitx-Web
一款 Rust Web 框架,使用 Rust 编写,性能高,使用简单,支持路由,支持中间件,支持异步编程,支持 WebSocket,支持 WebRTC,支持 WebGL,支持 WebGPU,支持 WebAssembly,支持 WebCrypto,支持 WebStorage,支持 WebAudio,支持 WebVTT,支持 WebIDL
快速开始
- 创建一个新项目,
rust
cargo init example-api- 安装 actix-web 依赖
bash
cargo add actix-web- 在 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
- 安装数据库依赖
bash
cargo add r2d2
cargo add r2d2_sqlite- 连接数据库
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
}