Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add middleware::from_extractor_with_state #1373

Closed
dmarku opened this issue Sep 12, 2022 · 5 comments · Fixed by #1396
Closed

Add middleware::from_extractor_with_state #1373

dmarku opened this issue Sep 12, 2022 · 5 comments · Fixed by #1396
Labels
A-axum C-feature-request Category: A feature request, i.e: not implemented / a PR.

Comments

@dmarku
Copy link

dmarku commented Sep 12, 2022

Bug Report

Version

test-axum-extractor v0.1.0
├── axum v0.6.0-rc.2
│   ├── axum-core v0.3.0-rc.2

Platform

Linux hostname 5.19.8-100.fc35.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Sep 8 19:23:03 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Description

Hi! I've been happily using Axum on a small server prototype and started migrating to v0.6.0 because the state feature looks very convenient for simplifying the application code. However, I've encountered an issue I can't explain on my own.

I'm defining an extractor that requires state via a FromRef<S> trait bound as described in https://docs.rs/axum/0.6.0-rc.2/axum/extract/struct.State.html#for-library-authors and try to use it as a middleware with middleware::from_extractor directly on a handler. I'd expected this to work and found no information to the contrary in the documentation on state and extractors. Instead it fails with an error at compile time. I'm not sure whether this is a bug or if I'm using Axum in an unintended way.

Minimal Example that produces the unexpected behavior:

use std::convert::Infallible;

use axum::{
    async_trait,
    extract::{FromRef, FromRequestParts},
    handler::Handler,
    http::request::Parts,
    middleware, Server,
};

async fn handler() -> &'static str {
    "ok"
}

#[derive(Clone)]
struct AppState;

#[derive(Clone)]
struct Data;

#[async_trait]
impl<S> FromRequestParts<S> for Data
where
    S: Send + Sync,
    // commenting out the line below eliminates the compiler error and the server starts and responds as intended
    AppState: FromRef<S>,
{
    type Rejection = Infallible;
    async fn from_request_parts(_: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
        Ok(Data)
    }
}

#[tokio::main]
async fn main() {
    let address = &"127.0.0.1:3000".parse().unwrap();
    println!("listening on {}", address);
    Server::bind(address)
        .serve(
            handler
                .layer(middleware::from_extractor::<Data>())
                .with_state(AppState)
                .into_make_service(),
        )
        .await
        .unwrap()
}

The compiler error is as follows:

   Compiling test-axum-extractor v0.1.0
error[E0599]: no method named `with_state` found for struct `Layered` in the current scope
  --> src/main.rs:41:18
   |
41 |                 .with_state(AppState)
   |                  ^^^^^^^^^^ method not found in `Layered<FromExtractorLayer<Data>, fn() -> impl Future<Output = &'static str> {handler}, ((),), _, _>`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `test-axum-extractor` due to previous error

Thanks in advance, I'd be happy to provide more details if necessary. 🙂

@davidpdrsn
Copy link
Member

@jplatte
Copy link
Member

jplatte commented Sep 13, 2022

@davidpdrsn the question was about from_extractor, not from_fn. Maybe we need from_extractor_with_state?

@davidpdrsn davidpdrsn reopened this Sep 13, 2022
@davidpdrsn
Copy link
Member

Ah sorry my bad. Yes that makes sense to have! Although using extractors is easy in from_fn middleware so can make one that runs the extractor and immediately calls "next"

@davidpdrsn davidpdrsn changed the title Can't use an extractor with trait bounds on state as a middleware Add middleware::from_extractor_with_state Sep 13, 2022
@davidpdrsn davidpdrsn added C-feature-request Category: A feature request, i.e: not implemented / a PR. A-axum labels Sep 13, 2022
@dmarku
Copy link
Author

dmarku commented Sep 13, 2022

Hi, thanks for the responses!

Ah sorry my bad. Yes that makes sense to have! Although using extractors is easy in from_fn middleware so can make one that runs the extractor and immediately calls "next".

Yeah, that's the tricky part. 🙂 I'm actually using a middleware as "glue code" right now to get the application running.

I'd like to have a go at submitting a PR myself for that, but I have other priorities for the coming weeks and can't say for certain that I'll find the time for it. I have a rough idea how I'd go about it but I'm not sure how involved the changes would actually become.

@davidpdrsn
Copy link
Member

It should be very similar to #1342

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-axum C-feature-request Category: A feature request, i.e: not implemented / a PR.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants