How to pass data to endpoints with rust-rocket

74 views Asked by At

I have a file called main.rs and a file rocket.rs. The first one is used to launch rocket defined in the other file:

main.rs

#[tokio::main]
async fn main(){
    let rocket = rocket();
    rocket.launch().await;
}

The other one has the rocket function and uses templates with Tera to pass information to the HTML.

rocket.rs

#[get("/end_point_example")]
fn end_point_example() -> Template {
    let context: HashMap<&str, &str> = [("data1", "value1"), ("data2","value1")]
        .iter().cloned().collect();
    Template::render("end_point_example", &context)
}

#[launch]
pub fn rocket() ->_ {
    rocket::build()
        .mount("/static", FileServer::from("static"))
        .mount("/", routes![end_point_example])
        .attach(Template::fairing())
}

This works perfectly fine, but the problem is that I have the context values of the endpoint (in this case value1 and value2) in the main file. How do I pass them from main.rs to the endpoints in rocket.rs?

I have seen this approach that uses the manage() method:

use std::sync::atomic::AtomicUsize;

struct HitCount {
    count: AtomicUsize
}

#[launch]
pub fn rocket() ->_ {
    rocket::build()
        .manage(HitCount { count: AtomicUsize::new(0) });
        .mount("/static", FileServer::from("static"))
        .mount("/", routes![end_point_example])
        .attach(Template::fairing())
}

#[get("/count")]
fn count(hit_count: &State<HitCount>) -> String {
    let current_count = hit_count.count.load(Ordering::Relaxed);
    format!("Number of visits: {}", current_count)
}

The problem is that the build and manage commands should be applied in the rocket.rs file so it isn't helpful. Do you have any suggestion?

(Note: consider that obviously I don't need the value1 and value2 to change dynamically. Once I evaluate them in the main, they remain the same for the whole run.)

1

There are 1 answers

0
Matteo B On

It's not mandatory to use the manage() function after the build() in the rocket.rs file, this solution works fine:

main.rs

struct MyData {
    data: usize,
}

#[tokio::main]
async fn main(){
    let data =  MyData{data:12};
    let rocket = rocket().manage(data);
    rocket.launch().await;
 }

rocket.rs

#[get("/end_point")]
fn end_point(state: &State<MyData>) -> Template {
    let context: HashMap<&str, String> = [("data", 
               state.data.to_string())]
        .iter().cloned().collect();
Template::render("end_point", &context)
}

#[launch]
pub fn rocket() ->_ {
    rocket::build()
        .mount("/static", FileServer::from("static"))
        .mount("/", routes![end_point])
        .attach(Template::fairing())
 }