Struct actix_web::web::Data Offcial document is actix_web::web::Data - Rust.
code example + http server
/*
~~~Cargo.toml
[package]
name = "actix-data-example"
version = "0.1.0"
authors = ["ncaq <[email protected]>"]
edition = "2018"
[dependencies]
actix-web = "1.0.0-rc"
~~~
*/
use actix_web::*;
use std::sync::Mutex;
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() -> std::io::Result<()> {
HttpServer::new(|| {
let data = web::Data::new(Mutex::new(MyData { counter: 0 }));
App::new()
// Store `MyData` in application storage.
.data(data.clone())
.service(web::resource("/index.html").route(web::get().to(index)))
})
.bind("0.0.0.0:3000")?
.run()
}
But, It is failed.
I received message App data is not configured, to configure use App::data().
This simular problem posted on stack overflow.
rust - Actix-Web reports "App data is not configured" when processing a file upload - Stack Overflow
I found workaround, but it is not work.
/*
~~~Cargo.toml
[package]
name = "actix-data-example"
version = "0.1.0"
authors = ["ncaq <[email protected]>"]
edition = "2018"
[dependencies]
actix-web = "1.0.0-rc"
env_logger = "0.6.0"
~~~
*/
use actix_web::*;
use std::sync::*;
fn main() -> std::io::Result<()> {
std::env::set_var("RUST_LOG", "actix_web=trace");
env_logger::init();
HttpServer::new(|| {
App::new()
.wrap(middleware::Logger::default())
.data(Mutex::new(ActixData::default()))
.service(web::resource("/index/").route(web::get().to(index)))
.service(web::resource("/create/").route(web::get().to(create)))
})
.bind("0.0.0.0:3000")?
.run()
}
fn index(actix_data: web::Data<Mutex<ActixData>>) -> HttpResponse {
println!("actix_data: {:?}", actix_data);
HttpResponse::Ok().body(format!("{:?}", actix_data))
}
fn create(actix_data: web::Data<Mutex<ActixData>>) -> HttpResponse {
println!("actix_data: {:?}", actix_data);
actix_data.lock().unwrap().counter += 1;
HttpResponse::Ok().body(format!("{:?}", actix_data))
}
/// actix-webが保持する状態
#[derive(Debug, Default)]
struct ActixData {
counter: usize,
}
This can escape App data is not configured.
But, ActixData is reset to default after about 30 seconds.
I do not know what is happening.
It is true that the code of the official document does not work.
I listen workaround it is not work too.
/*
~~~Cargo.toml
[package]
name = "actix-data-example"
version = "0.1.0"
authors = ["ncaq <[email protected]>"]
edition = "2018"
[dependencies]
actix-web = "1.0.0-rc"
env_logger = "0.6.0"
~~~
*/
use actix_web::*;
use std::sync::*;
fn main() -> std::io::Result<()> {
std::env::set_var("RUST_LOG", "actix_web=trace");
env_logger::init();
HttpServer::new(|| {
let data = Arc::new(Mutex::new(ActixData::default()));
App::new()
.wrap(middleware::Logger::default())
.data(data.clone())
.service(web::resource("/index/").route(web::get().to(index)))
.service(web::resource("/create/").route(web::get().to(create)))
})
.bind("0.0.0.0:3000")?
.run()
}
fn index(actix_data: web::Data<Arc<Mutex<ActixData>>>) -> HttpResponse {
println!("actix_data: {:?}", actix_data);
HttpResponse::Ok().body(format!("{:?}", actix_data))
}
fn create(actix_data: web::Data<Arc<Mutex<ActixData>>>) -> HttpResponse {
println!("actix_data: {:?}", actix_data);
actix_data.lock().unwrap().counter += 1;
HttpResponse::Ok().body(format!("{:?}", actix_data))
}
/// actix-webが保持する状態
#[derive(Debug, Default)]
struct ActixData {
counter: usize,
}
This data reset too.
I asked people in the rust-jp community to tell you the correct answer.
/*
~~~Cargo.toml
[package]
name = "actix-data-example"
version = "0.1.0"
authors = ["ncaq <[email protected]>"]
edition = "2018"
[dependencies]
actix-web = "1.0.0-rc"
env_logger = "0.6.0"
~~~
*/
use actix_web::*;
use std::sync::*;
fn main() -> std::io::Result<()> {
std::env::set_var("RUST_LOG", "actix_web=trace");
env_logger::init();
let data = Arc::new(Mutex::new(ActixData::default()));
HttpServer::new(move || {
App::new()
.wrap(middleware::Logger::default())
.data(data.clone())
.service(web::resource("/index/").route(web::get().to(index)))
.service(web::resource("/create/").route(web::get().to(create)))
})
.bind("0.0.0.0:3000")?
.run()
}
fn index(actix_data: web::Data<Arc<Mutex<ActixData>>>) -> HttpResponse {
println!("actix_data: {:?}", actix_data);
HttpResponse::Ok().body(format!("{:?}", actix_data))
}
fn create(actix_data: web::Data<Arc<Mutex<ActixData>>>) -> HttpResponse {
println!("actix_data: {:?}", actix_data);
actix_data.lock().unwrap().counter += 1;
HttpResponse::Ok().body(format!("{:?}", actix_data))
}
/// actix-webが保持する状態
#[derive(Debug, Default)]
struct ActixData {
counter: usize,
}
Anyway, I think that the official document which does not move should be corrected.
I do not know specifically how to fix it, but…
in original example you store different types.
fixed in master
Sorry to bother you all I have a similar issue I read the specs and I tried the outside arc clone.
I upgraded my application from 0.5.x to 1.0.9 and I ran into a similar issue.
actix = "0.8.3"
actix-web = "1.0.8"
actix-cors = "0.1.*"
pub trait ApiEndPoints {
fn register_endpoints(config: &mut web::ServiceConfig) -> &mut web::ServiceConfig;
}
pub struct AppState {
db: Addr<DbExecutor>,
coap_client: Addr<CoAP>,
send_email: Addr<SendEmail>,
logger: Addr<LogActor>,
qr_code: Addr<QrCodeActor>,
image: Addr<ImageActor>,
config: Arc<RwLock<HashMap<String, String>>>,
}
fn main() {
dotenv().ok();
::std::env::set_var("RUST_LOG", "actix_web=error");
env_logger::init();
let config: Arc<RwLock<HashMap<String, String>>> = Arc::new(RwLock::new(HashMap::new()));
......
let data = web::Data::new(Mutex::new(AppState {
db: addr_db.clone(),
coap_client: addr_coap.clone(),
send_email: addr_email.clone(),
qr_code: addr_qr_code.clone(),
config: config.clone(),
logger: addr_logger_app_state.clone(),
image: addr_image.clone()
}));
HttpServer::new(move || {
let app = App::new()
.wrap(middleware::Logger::default())
.wrap(
Cors::new()
.allowed_methods(vec!["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD"])
.max_age(3600)
)
.configure(|mut service| {
let mut service = domain_model::evse_resource::endpoints::EvseResourceApi::register_endpoints(&mut service);
let mut service = domain_model::user::endpoints::UserApi::register_endpoints(&mut service);
let service = domain_model::charging_process::endpoints::ChargingApi::register_endpoints(&mut service);
}).register_data(data.clone());
app
})
.bind(api_server_address.clone())
.unwrap()
.start();
println!("Started http server: {}", api_server_address.clone());
let _ = sys.run();
}
as you can see the "move" as well as the Arc + Mutex do exist since
web::Data::new(T) -> Data<T>(Arc<T>);
I still get the error message:
App data is not configured, to configure use App::data()
I am in hour 9 of coding so probably I am missing something obvious.
edit
got the problem. registered function needs to have the correct signature as well. I appologize if I caused any inconvenience. Maybe it's useful for someone else afterwards.
from:
fn create(
(state, params): (web::Data<AppState>, Json<CreateUserRequest>),
) -> impl Future<Item=HttpResponse, Error=HttpResponse> {
to:
fn create(
(state, params): (web::Data<Arc<Mutex<AppState>>>, Json<CreateUserRequest>),
) -> impl Future<Item=HttpResponse, Error=HttpResponse> {
I wasn't counting on this kind of resolve mechanism, I am also not quite sure why it works that way since the data is a tuple pushed on a vector of pointers but there are probably some good reasons for that. However there maybe is a better way of hinting possible mistakes. Maybe something like "no data for this route was found, please check App::data and the according method signature"
Anyhow I know talks is cheap. Thank you for your work.
I dont know thy this issue is closed it still continues I had to use lazy-static to initialize my data because actix-web doesnt simply work
@NikosEfthias i'm sure we can help you. Can you provide us a code snippet here or in the gitter chat so we can check what's going on.
@robjtede The issue was scoped configurations could not use the global app_dataI had to pass data of their own.
Most helpful comment
I asked people in the rust-jp community to tell you the correct answer.
Anyway, I think that the official document which does not move should be corrected.
I do not know specifically how to fix it, but…