Правильный тип возврата create_app

Я использую actix-web для создания http-сервера со встроенным в него состоянием / данными. Но vscode показывает мне, что функция create_app имеет неправильные аргументы в определении типа возвращаемого значения "App":

паб структура приложение

неверное количество аргументов типа: ожидается 2, найдено 1

ожидаемые аргументы типа 2rustc (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 (без универсального параметра), но все равно получил ошибку, что мне делать?

2 ответа

Первый, App принимает два аргумента универсального типа, App<AppEntry, Body>, вы дали только один.

Во-вторых, AppState не является AppEntry.

В-третьих, создание экземпляра App вне actix-web сложно, если не невозможно, так как типы, которые вам нужны из 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<Fn(&mut ServiceConfig)> {
    Box::new(move |cfg: &mut ServiceConfig| {
        cfg.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())
}

Узнать больше о ServiceConfigв документации api.

это действительно просто, но вам нужно импортировать AppEntry, и проблема в том, что AppEntry не экспортируется actix_web

поэтому вам необходимо обновить исходный код пакета

поэтому перейдите в /lib.rs, нажав ctrl + щелкните правой кнопкой мыши actix_web; затем добавьте следующую строку после pub mod rt;

      pub mod app_service ;

тогда вам нужно сначала обновить кеш

      cargo clean
cargo update
cargo fetch
cargo build

теперь все хорошо, и вы можете импортировать AppEntry, используя этот синтаксис

      use actix_web::app_service::AppEntry;

после импорта записи приложения вы можете делать все, что захотите, структурируя свой код в mvc или делая все, что захотите.

Другие вопросы по тегам