如何在 Actix-Web 中返回已配置的应用程序?

问题描述 投票:0回答:3

我正在使用 actix-web 创建一个嵌入了状态/数据的 httpserver。但是 vscode 告诉我

create_app
函数的返回值类型定义中有错误的参数
App<AppState>
:

pub struct App<T, B>
wrong number of type arguments: expected 2, found 1
expected 2 type argumentsrustc(E0107)

app.rs:

use crate::api;
use crate::model::DbExecutor;
use actix::prelude::Addr;
use actix_web::{error, http::Method, middleware::Logger, web, App, HttpResponse};

pub struct AppState {
    pub db: Addr<DbExecutor>,
}

pub fn create_app(db: Addr<DbExecutor>) -> App<AppState> {
    App::new().data(AppState { db }).service(
        web::resource("/notes/").route(web::get().to(api::notes))
    );
}

main.rs:

fn main() {
    HttpServer::new(move || app::create_app(addr.clone()))
        .bind("127.0.0.1:3000")
        .expect("Can not bind to '127.0.0.1:3000'")
        .start();
}

由于“service”方法的返回类型是“Self”,类型为 actix_web::App,我尝试将返回类型修改为 App(不带泛型参数),但仍然出现错误,我该怎么办?

rust actix-web
3个回答
8
投票

首先,

App
采用两个泛型类型参数,
App<AppEntry, Body>
,您只给出了一个。

第二,

AppState
不是
AppEntry

第三,在 actix-web 之外实例化

App
即使不是不可能,也是很困难的,因为你需要的 actix-web 类型不是公开的。

相反,您应该使用 configure 来实现相同的目的,这是一个简化的示例:

use actix_web::web::{Data, ServiceConfig};
use actix_web::{web, App, HttpResponse, HttpServer};

fn main() {
    let db = String::from("simplified example");

    HttpServer::new(move || App::new().configure(config_app(db.clone())))
        .bind("127.0.0.1:3000")
        .expect("Can not bind to '127.0.0.1:3000'")
        .run()
        .unwrap();
}

fn config_app(db: String) -> Box<dyn Fn(&mut ServiceConfig)> {
    Box::new(move |cfg: &mut ServiceConfig| {
        cfg.app_data(db.clone())
            .service(web::resource("/notes").route(web::get().to(notes)));
    })
}

fn notes(db: Data<String>) -> HttpResponse {
    HttpResponse::Ok().body(["notes from ", &db].concat())
}

api 文档
中阅读有关 ServiceConfig 的更多信息。


0
投票

AppEntry
类型是故意且明确不公开的,也不会公开。有两种方法可以生成通过函数配置的
App

  1. 返回类型 o' doom:您可以使用此测试中的示例来设置函数的适当返回类型:

      pub fn my_app() -> App<
          impl ServiceFactory<
              ServiceRequest,
              Response = ServiceResponse<impl MessageBody>,
              Config = (),
              InitError = (),
              Error = Error,
          >,
      > {
          App::new()
        }
    
  2. 使用

    App::configure()
    方法 配置“空白”
    App
    实例,按照文档中的示例:

    // this function could be located in different module
    fn config(cfg: &mut web::ServiceConfig) {
        cfg.service(web::resource("/test")
            .route(web::get().to(|| HttpResponse::Ok()))
            .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
        );
    }
    
    App::new()
        .configure(config);
    

-1
投票

真的很简单,但是你需要导入AppEntry 问题是 Actix_web 没有导出 AppEntry

所以你需要更新包的原始代码

所以按 ctrl + 右键单击 actix_web 转到 /lib.rs; 然后在 pub mod rt 之后添加下一行;

pub mod app_service ;

那么你需要先更新缓存

cargo clean
cargo update
cargo fetch
cargo build

现在一切都很好,您可以使用此语法导入 AppEntry

use actix_web::app_service::AppEntry;

导入应用程序条目后,您可以通过将代码构造为 mvc 或做任何您想做的事情来做您想做的事情

© www.soinside.com 2019 - 2024. All rights reserved.