I'm using actix-web to create a httpserver with state/data embedded in it. But vscode show me that the create_app
function has wrong arguments in its return value type definition 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();
}
As return type of "service" method is "Self" which is type actix_web::App, I tried modify return type to App (without generic parameter) but still got error, what should I do?
First, App
takes two generic type arguments, App<AppEntry, Body>
, you've only given one.
Second, AppState
is not AppEntry
.
Third, instantiating App
outside actix-web is hard, if not impossible, as the types you need from actix-web are not public.
Instead, you should use configure to achieve the same, here is a simplified example:
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())
}
Read more about ServiceConfig
in the api documentation.