Hi,
Is there a way to pass parameters to a function inside route for example:
.service(web::resource("/user/{name}").route(web::get().to(with_param)))
.default_service(
// 404 for GET request
web::resource("")
.route(web::get().to(testit("ok")))
// all requests that are not `GET`
.route(
web::route()
.guard(guard::Not(guard::Get()))
.to(|| HttpResponse::MethodNotAllowed()),
),
)
And the function example!
fn testit(param: String) -> String {
println!("{}", param);
param
}
Thank you
Probably no. What's use case? What problem do you want to solve?
If you want to split route based on some argument, just split code into function and write two routes.
@max-frai
I want to pass some arguments to the functions depend on the requests of users.
So I can get and serve the right datas.
I have a function that call models connected to my database and serve specific results depend on parameters requested, and then callback with JSON format readable using Javascript from the FrontEnd.
I tried a test like this (Notice that I need to declare a TYPE for this function but it return an error when doing that):
fn testit() {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("set DATABASE_URL");
let conn = MysqlConnection::establish(&database_url).unwrap();
let types = 1;
let period = 2;
let first_date = 0;
let result: Vec<chart_models::MultiArr> = bucks_models::bucks::bucks_infos(types, period, first_date, &conn);
println!("{:#?}", result);
}
Router:
.default_service(
web::resource("")
.route(web::get().to(testit)) // <- Here is the function
.route(
web::route()
.guard(guard::Not(guard::Get()))
.to(|| HttpResponse::MethodNotAllowed()),
),
)
But the server shutdown (When accessing to: 127.0.0.1:8080) with this error message:
thread 'actix-rt:worker:0' panicked at 'called `Result::unwrap()` on an `Err` va
lue: Empty', src\libcore\result.rs:999:5
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
Panic in Arbiter thread, shutting down system.
Not sure, but I think that Path ("Extract typed information from the request's path") might be what you are looking for here.
As the people above have said, you should probably use the path extractor but I'm going to guess that's what you did with the with_param function.
To do the thing that you originally wanted, use a closure instead.
use actix_web::{guard, web, App, HttpResponse, HttpServer};
fn main() {
HttpServer::new(|| {
App::new()
// .service(web::resource("/user/{name}").route(web::get().to(with_param))) // I don't have the `with_param` function
.default_service(
// 404 for GET request
web::resource("")
.route(web::get().to(|| testit("ok".to_string()))) // Changed to a closure
// all requests that are not `GET`
.route(
web::route()
.guard(guard::Not(guard::Get()))
.to(|| HttpResponse::MethodNotAllowed()),
),
)
})
.bind("127.0.0.1:8080")
.expect("Failed to bind to the server.")
.run()
.expect("Failed to run the server.")
}
fn testit(param: String) -> String {
println!("{}", param);
param
}
@HiruNya Awesome, It's what I was looking for :)
What if testit() is a post request ? such as :
fn testit(item: web::Json<MyObj>, param: String) -> HttpResponse {
...
}
@zhangnew Make the closure take a web::Json<MyObj> struct.
e.g.
web::post().to(|item: web::Json<MyObj>| testit(item, "ok".to_string()))
@HiruNya thank you, that's worked.
Most helpful comment
As the people above have said, you should probably use the path extractor but I'm going to guess that's what you did with the
with_paramfunction.To do the thing that you originally wanted, use a closure instead.