Skip to content

Remove Clone trait requirement from SessionStore #33

Closed
@tadic-luka

Description

@tadic-luka

I am writing some web server using axum library where I use multiple traits and put them in request extensions by converting them to Arc so that I don't have to make every handler accept generic parameters. Unfortunately I can't do that for SessionStore (which I use in a middleware for checking authentication) since it requires implementor to also implement Clone, making it non object safe. Is there a possibility to remove Clone requirement in next major version?

Example with handlers accepting generic parameters:

fn configure<U, T, S>(user_service: U, transaction_service: T, session_store: S) -> Router
  where 
         U: UserService,
         T: TransactionService ,
         S: SessionStore
{
  Router::new()
          .route("/", handlers::index::<U>)
          .route("/user", handlers::user::overview::<U, T, S>)
          .layer(Extension(user_service))
          .layer(Extension(transaction_service))
          .layer(Extension(session_store))
}

// in handlers/index.rs
async fn index<U: UserService>(Extension(service): Extension<U>) -> impl IntoResponse {
//some stuff
}

// in handlers/user.rs
async fn overview<U: UserService, T: TransactionService, S: SessionStore>(
       Extension(user_service): Extension<U>,
       Extension(transaction_service): Extension<T>,
       Extension(session_store): Extension<S>,
) -> impl IntoResponse {
//some stuff
}

And new way which I would be able to do if SessionStore is object safe:

fn configure<U, T, S>(user_service: U, transaction_service: T, session_store: S) -> Router
  where 
         U: UserService,
         T: TransactionService ,
         S: SessionStore
{
  Router::new()
          .route("/", handlers::index)
          .route("/user", handlers::user::overview)
          .layer(Extension(Arc::new(user_service) as Arc<dyn UserService>))
          .layer(Extension(Arc::new(transaction_service) as Arc<dyn TransactionService>))
           .layer(Extension(Arc::new(session_store) as Arc<dyn SessionStore>)) // Not object safe, this will fail
}

// in handlers/index.rs
async fn index(Extension(service): Extension<Arc<dyn UserService>>) -> impl IntoResponse {
//some stuff
}

// in handlers/user.rs
async fn overview(
       Extension(user_service): Extension<Arc<dyn UserService>>,
       Extension(transaction_service): Extension<Arc<dyn TransactionService>>,
       Extension(session_store): Extension<Arc<dyn SessionStore>>,
) -> impl IntoResponse {
//some stuff
}

This will make function signature smaller when I start adding more traits.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions