jeudi 13 janvier 2022

How to design an object-database relation in Rust?

I'm creating a Rust web application and I will need popular data types like User, Role, Privilege, etc. All of them needs to be stored in the database so for each model I need to implement an SQL query generation logic. Now I'm thinking where to put that logic in the code.

I have some ideas but all of them seem to have drawbacks.

  1. Use e.g. Create Trait. Which then I would implement for each data type.

    trait Create {
        fn create(&self, client: &DbClient) -> Result<(), Error>;  
    }
    

    This is ok but I would like to put all the SQL logic inside a dedicated module, not tie it to data model. Also, I would have to pass &DbClient every time.

  2. Create dedicated module e.g. Storage which would have &DbClient inside and expose an API for each concrete data type.

    struct Storage {
        client: &DbClient,
    }
    
    impl Storage {
         async fn create_user(&self, &User) -> Result<(), Error> { }
         async fn create_role(&self, &Role) -> Result<(), Error> { }
    }
    

    This one will result in a single struct with so many methods which I doubt is an elegant solution.

  3. Create StorageUser, StorageRole, etc. but this time I would have some many generic objects to pass and it also doesn't look good for me.

    struct StorageUser {
        client: &DbClient,
    }
    
    impl StorageUser {
         async fn create(&self, &User) -> Result<(), Error> { }
    }
    
    struct StorageRole {
        client: &DbClient,
    }
    
    impl StorageRole {
         async fn create(&self, &Role) -> Result<(), Error> { }
    }
    

How would you approach it? I'm aware this is highly opinion-based question.

Aucun commentaire:

Enregistrer un commentaire