Actix
Actix 是一个基于 Rust 的 web 框架,可以提供对 HTTP/1、HTTP/2,以及 TLS(HTTPS)的支持,设置还支持 WebSocket,而且速度非常快。
安装和使用
先创建一个项目:
cargo new webservice
在 webservice/Cargo.toml
添加 actix 依赖:
[dependencies]
actix-web = "3"
然后可以 build 一下,就会下载相关依赖:
cargo build
可能需要一点儿时间,尤其网络不是那么好的情况下,多 build 几次就行了。
按照 crate 官方文档的例子,我们可以搭建一个最简单的 web service:
use actix_web::{get, web, App, HttpServer, Responder};
#[get("/{id}/{name}/index.html")]
async fn index(web::Path((id, name)): web::Path<(u32, String)>) -> impl Responder {
format!("Hello {}! id:{}", name, id)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(||
App::new()
.service(index)
)
.bind("127.0.0.1:8080")?
.run()
.await
}
然后访问 http://127.0.0.1:8080/1/eagle/index.html
获取请求参数
use actix_web::{get, web, App, HttpServer};
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
pub enum ResponseType {
Token,
Code
}
#[derive(Deserialize)]
pub struct AuthRequest {
id: u64,
response_type: ResponseType,
}
#[get("/api/v1/get")]
async fn get1(web::Query(info) : web::Query<AuthRequest>) -> String {
format!("Authorization request for client with id={} and type={:?}!", info.id, info.response_type)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(||
App::new()
.service(get1)
)
.bind("127.0.0.1:8080")?
.run()
.await
}
访问 http://localhost:8080/api/v1/get?id=1&response_type=Token
访问效果如下:
获取 body 体的内容
在 webservice/Cargo.toml
添加 serde 依赖:
[dependencies]
serde = { version = "1.0.133", features = ["derive"] }
use actix_web::{web, App, HttpServer, post};
use serde::{Deserialize};
#[derive(Deserialize)]
struct FormData {
name: String,
}
#[post("/api/v1/post")]
async fn post1(form: web::Form<FormData>) -> String {
format!("Welcome {}!", form.name)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(||
App::new()
.service(post1)
)
.bind("127.0.0.1:8080")?
.run()
.await
}
访问效果如下:
返回 JSON 数据
use actix_web::{web, App, HttpServer, post, Result, Responder};
use serde::{Serialize, Deserialize};
#[derive(Deserialize)]
struct FormData {
name: String,
age: u8,
}
#[derive(Serialize)]
struct SomeForm {
name: String,
age: u8
}
#[post("/api/v1/post")]
async fn post1(form: web::Form<FormData>) -> Result<impl Responder> {
let obj = SomeForm {
name: form.name.to_string(),
age: form.age,
};
Ok(web::Json(obj))
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(||
App::new()
.service(post1)
)
.bind("127.0.0.1:8080")?
.run()
.await
}
访问效果:
静态服务
在 webservice
目录下添加 public
目录,再添加一些 html 文件。
在 webservice/Cargo.toml
添加 actix-files 依赖:
[dependencies]
actix-files = "0.5.0"
use std::env;
use actix_files as fs;
use actix_web::{App, HttpServer};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
let default_path = format!("{}/public", env!("CARGO_MANIFEST_DIR"));
let public_path = env::var("PUBLIC_PATH").unwrap_or(default_path);
App::new().service(fs::Files::new("/", &public_path).index_file("index.html"))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
访问效果: