rust - 使用函数装饰时,如何将 App 数据传递给 actix-web 中的服务路由处理程序函数?
问题描述
我在文档中找到了一个如何创建全局状态的示例,该状态受 Mutex 保护,在处理线程之间共享,可供所有路由处理程序使用。完美的!但是,我更喜欢使用附加到我的函数的属性来连接我的路由处理程序。我不知道使用属性函数并传入全局状态的语法(如果允许)。
这是来自https://docs.rs/actix-web/1.0.2/actix_web/web/struct.Data.html的 actix-web 文档的示例
use std::sync::Mutex;
use actix_web::{web, App};
struct MyData {
counter: usize,
}
/// Use `Data<T>` extractor to access data in handler.
fn index(data: web::Data<Mutex<MyData>>) {
let mut data = data.lock().unwrap();
data.counter += 1;
}
fn main() {
let data = web::Data::new(Mutex::new(MyData{ counter: 0 }));
let app = App::new()
// Store `MyData` in application storage.
.register_data(data.clone())
.service(
web::resource("/index.html").route(
web::get().to(index)));
}
注意命名的路由处理程序index
是如何被传递给web::Data
.
现在这里是我的一些代码片段。
use actix_web::{get, App, HttpResponse, HttpServer, Responder};
pub mod request;
pub mod routes;
const SERVICE_NAME : &str = "Shy Rules Engine";
const SERVICE_VERSION : &str = "0.1";
#[get("/")]
fn index() -> impl Responder {
HttpResponse::Ok().body(format!("{} version {}", SERVICE_NAME, SERVICE_VERSION))
}
mod expression_execute {
#[post("/expression/execute")]
fn route(req: web::Json<ExpressionExecuteRequest>) -> HttpResponse {
// ... lots of code omitted ...
if response.has_error() {
HttpResponse::Ok().json(response)
}
else {
HttpResponse::BadRequest().json(response)
}
}
}
pub fn shy_service(ip : &str, port : &str) {
HttpServer::new(|| {
App::new()
.service(index)
.service(expression_execute::route)
})
.bind(format!("{}:{}", ip, port))
.unwrap()
.run()
.unwrap();
}
注意我是如何调用方法App::service
来连接我的路由处理程序的。
还要注意我的路由处理程序如何没有接收到全局状态(因为我还没有将它添加到我的应用程序中)。如果我使用与文档类似的模式register_data
来创建全局 App 数据,我应该对我的方法签名、get
和post
属性以及其他任何内容进行哪些更改,以便我可以将该全局状态传递给处理程序?
还是不能使用get
andpost
属性来访问全局状态?
解决方案
您列出的两种情况确实没有太大区别:
//# actix-web = "1.0.8"
use actix_web::{get, web, App, HttpResponse, HttpServer, Responder};
use std::sync::Mutex;
const SERVICE_NAME : &str = "Shy Rules Engine";
const SERVICE_VERSION : &str = "0.1";
struct MyData {
counter: usize,
}
#[get("/")]
fn index(data: web::Data<Mutex<MyData>>) -> impl Responder {
let mut data = data.lock().unwrap();
data.counter += 1;
println!("Endpoint visited: {}", data.counter);
HttpResponse::Ok().body(format!("{} version {}", SERVICE_NAME, SERVICE_VERSION))
}
pub fn shy_service(ip : &str, port : &str) {
let data = web::Data::new(Mutex::new(MyData{ counter: 0 }));
HttpServer::new(move || {
App::new()
.register_data(data.clone())
.service(index)
})
.bind(format!("{}:{}", ip, port))
.unwrap()
.run()
.unwrap();
}
fn main() {
shy_service("127.0.0.1", "8080");
}
curl
您可以通过简单的 http 端点来验证它是否有效。对于多个提取器,您必须使用元组:
#[post("/expression/execute")]
fn route((req, data): (web::Json<ExpressionExecuteRequest>, web::Data<Mutex<MyData>>)) -> HttpResponse {
unimplemented!()
}
推荐阅读
- amazon-web-services - AWS AppSync - 放大代码生成类型而不创建任何内容
- azure - 在哪里可以找到 azure 身份范围及其权限级别的列表?
- r - R 编程:“[[k]][1:nrow(my_data)]”在我的建模函数中做了什么?寻找对 R 代码的更多理解
- javascript - 如何使用其中的文本大小调整 div 宽度
- java - 如何在 javafx 中实现可调整性?
- django - 将 Django 连接到 Microsoft SQL 数据库
- sql - 是否可以在 plpgsql 中编写 time_bucket_gapfill 替代方案
- reactjs - 没有正文的 axios 发布请求到达没有标头的服务器
- angular - 在 Firebase 上检索子索引
- python - 为什么我不断收到 ValueError:Python 中的数学域错误?