Request Handler - 请求处理程序 请求处理程序是一个异步函数能够从客户端请求中提取参数(impl FromRequest
),并且能返回可以被转换成HttpResponse
的数据类型(impl Responder
)。
请求处理会发生在两个阶段:
Handler
函数(对象)被调用,返回实现了Responder
特征的任意对象。
respond_to()
函数被上一步返回的对象调用,该函数将该对象转换为HttpResponse
或Error
。
Extractor
是actix-web
中一个功能强大的工具,能够帮助你轻易地处理和提取从客户端发来的请求中的数据,让程序员专注在逻辑处理上而不是如何提取数据上。另一个值得一提的点是,Extractor
是一个类型安全的信息提取器,提取的任何数据都需要提前设置好它的类型。
actix-web
提供了多种类型的extractors
来适用于不同场景。
Path Path
是用来从请求路径(URL) 中提取数据的提取器。路径(URL) 中可以被提取的部分被称为”动态片段 - dynaimc segments”,actix-web
使用{}
来标记。程序员可以从路径(URL) 中反序列化任意的变量。
use actix_web::{get, web, App, HttpServer, Result };#[get("/users/{user_id}/{friend}" )] async fn index (path: web::Path<(u32 , String )>) -> Result <String > { let (user_id, friend) = path.into_inner (); Ok (format! ("Welcome {}, user_id is {}" , friend, user_id)) } #[actix_web::main] async fn main () -> std::io::Result <()> { HttpServer::new (|| App::new ().service (index)) .bind (("127.0.0.1" , 8080 ))? .run () .await }
在上面的例子中,请求处理程序可以处理请求形态为/users/user_id<u32>/friend<String>
的URL。请求处理程序使用into_inner()
方法将URL
中定义的user_id
和friend
的数据赋值给一个元组(这里的元组会按函数体参数部分声明的顺序)。
匹配动态片段名提取数据 可以通过匹配动态数据名和Struct
字段名,来提取数据,这里的struct
需要实现来自serde
的Deserialize
的特征。
use actix_web::{get, web, Result };use serde::Deserialize;#[derive(Deserialize)] struct Info { user_id: u32 , friend: String , } #[get("/users/{user_id}/{friend}" )] async fn index (info: web::Path<Info>) -> Result <String > { Ok (format! ( "Welcome {}, user_id {}" , info.friend, info.user_id )) } #[actix_web::main] async fn main () -> std::io::Result <()> { use actix_web::{App, HttpServer}; HttpServer::new (|| App::new ().service (index)) .bind (("127.0.0.1" , 8080 ))? .run () .await }
非类型安全的一种变体 #[get("/users/{user_id}/{friend}" )] async fn index (req: HttpRequest) -> Result <String > { let name : String = req.match_info ().get ("friend" ).unwrap ().parse ().unwrap (); let userid : i32 = req.match_info ().query ("user_id" ).parse ().unwrap (); Ok (format! ("Welcome {}, user_id {}!" , name, userid)) } #[actix_web::main] async fn main () -> std::io::Result <()> { use actix_web::{App, HttpServer}; HttpServer::new (|| App::new ().service (index)) .bind (("127.0.0.1" , 8080 ))? .run () .await }
Query 用于从请求的query
中提取信息。针对类似的URL
形态,/?id=64&response_type=Code
, Query
可以提取键为id
和response_type
的值。
Struct actix_web::web::Query :
method - from_query
method - into_inner
use actix_web::{get, web};use serde::Deserialize;#[derive(Debug, Deserialize)] pub enum ResponseType { Token, Code, } #[derive(Debug, Deserialize)] pub struct AuthRequest { id: u64 , response_type: ResponseType, } #[get("/" )] async fn index (info: web::Query<AuthRequest>) - String { format! ("Authorization request for id = {} and type = {:?}!" , info.id, info.response_type) } #[get("/debug1" )] async fn debug1 (info: web::Query<AuthRequest>) -> String { dbg!("Authorization object = {:?}" , info.into_inner ()); "Ok" .to_string () } #[get("/debug2" )] async fn debug2 (info: web::Query<AuthRequest>) -> String { dbg!("Authorization object = {:?}" , info); "Ok" .to_string () }
可以通过QueryConfig 配置提取器进程。
Json Json
作为提取器能够将请求体反序列化为struct
(struct
必须实现serde::Deserialize
)。,可以使用JsonConfig 配置提取器进程。
Struct actix_web::web::Json :
method - into_inner()
use actix_web::{post, web, App};use serde::Deserialize;#[derive(Deserialize)] struct Info { username: String , } #[post("/" )] async fn index (info: web::Json<Info>) -> String { format! ("Welcome {}!" , info.username) }
这个请求处理器仅在请求内容为application/x-www-form-urlencoded
格式时生效。可以使用FormConfig 配置。
Struct actix_web::web::Form :
method - into_inner()
use actix_web::{post, web, App};use serde::Deserialize;#[derive(Deserialize)] struct Info { name: String , } #[post("/" )] async fn index (form: web::Form<Info>) -> Result <String > { Ok (format! ("Welcome {}!), form.name) }
Others Other extractors:
Data - accessing pieces of application state.
HttpRequest - HttpRequest
is itself an extractor, in case you need access to other parts of the request.
String - can convert a request’s payload to a String. Example
Bytes - can convert a request’s payload into Bytes. Example
Payload - Low-level payload extractor primarily for building other extractors. Example