Is my code using Arc and DB through Rocket correct?

Hello!

I was looking for some feedback on the approach that I chose to use for making a query to a database using Rocket. The code is working, however I just want to make sure I'm going about this in the correct manner.

Here's what I'm doing -

First I create a repository struct:

pub struct TodosRepo;

impl TodosRepo {
    pub fn get_all_todos(&self, client: &mut postgres::Client) -> Result<Vec<TodoEntity>, String> {
        // ... code to get todos from db ...
        Ok(todos)
    }
}

Then in the Rocket launch function I add the TodosRepo in an Arc as I need it to be thread safe.

#[launch]
fn rocket() -> _ {
    rocket::build()
        .mount("/", routes![index])
        .attach(TodosDbConn::fairing())
        .manage(Arc::new(TodosRepo {})) // <-- here
}

Next, in my handler I'm cloning the Arc to be able to use it within the closure of conn.run. I was having trouble when the TodosRepo was not an Arc, which I suppose makes sense b/c it wouldn't be thread safe.

#[get("/")]
async fn index(
    conn: TodosDbConn,
    todos_repo: &rocket::State<Arc<TodosRepo>>,
) -> (Status, Json<ServerResponse<Vec<TodoEntity>>>) {
    let todos_repo = Arc::clone(&todos_repo);

    conn.run(move |client| {
        let todos = todos_repo.get_all_todos(client);
        match todos {
            Ok(todos) => {
                // ... code to construct response ...
                (Status::Ok, Json(res))
            }
            Err(e) => {
                // ... code to construct response ...
                (Status::InternalServerError, Json(res))
            }
        }
    })
    .await
}

And that's it! I'm not very confident in my Rust yet so any thoughts would be much appreciated.

Also, I'm curious, in Rust, is the Repository Pattern common at all or is there a more Rusty approach?

Thanks!

Yes, Arc is the correct type to have a shared reference to data across different scopes and threads.

1 Like

Thanks very much. Is splitting the code like this into a struct that deals with the DB and an http handler function which just calls it an idiomatic approach or is there a more Rusty way?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.