axum icon indicating copy to clipboard operation
axum copied to clipboard

`Router::route_service()` example code is out of date

Open jwodder opened this issue 1 year ago • 7 comments

The current documentation for axum::Router::route_service() has an example that contains the following lines:

        // Services whose response body is not `axum::body::BoxBody`
        // can be wrapped in `axum::routing::any_service` (or one of the other routing filters)
        // to have the response body mapped
        any_service(service_fn(|_: Request| async {
            let res = Response::new(Body::from("Hi from `GET /`"));
            Ok::<_, Infallible>(res)
        }))

        ...

        // This service's response body is `axum::body::BoxBody` so
        // it can be routed to directly.
        service_fn(|req: Request| async move {
            let body = Body::from(format!("Hi from `{} /foo`", req.method()));
            let res = Response::new(body);
            Ok::<_, Infallible>(res)
        })

However, despite what the comments in the code say, both responses appear to have axum::body::Body as their bodies, and there is currently no axum::body::BoxBody in the crate. I assume that BoxBody was removed in an earlier version and the example was only partially updated, but that just raises the question: What is any_service() good for now?

jwodder avatar Jan 25 '24 13:01 jwodder

Ah yes that example is indeed out of date. axum always uses axum::body::Body for requests and responses since 0.7.

What is any_service() good for now?

It can still be used to route to any service regardless of the HTTP method.

davidpdrsn avatar Jan 25 '24 13:01 davidpdrsn

What is any_service() good for now?

It can still be used to route to any service regardless of the HTTP method.

So what happens if I supply a service_fn() but don't wrap it in any_service()? Will only GET requests be routed to it?

jwodder avatar Jan 25 '24 13:01 jwodder

"Supply" it how?

davidpdrsn avatar Jan 25 '24 14:01 davidpdrsn

Ah, I missed that the non-any_service() bit of the example was using route_service() instead of route(). So the main point of any_service() is to let you pass a service to route() instead of to route_service()?

jwodder avatar Jan 25 '24 14:01 jwodder

Exactly. You might also wanna run the MethodRouter, without using Router at all.

davidpdrsn avatar Jan 25 '24 14:01 davidpdrsn

It would be great if the example code or documentation could illustrate how to use this with State and Path.

I have a function like so

async fn handler(State(db): State<Arc<Database>>,
    Path(id): Path<String>,
) 

and providing to route_service("/:id", service_fn(handler)) results in a compiler error.

There isn't any documentation or examples to figure out how to resolve this unfortunately

JosiahParry avatar Aug 08 '24 16:08 JosiahParry

@JosiahParry service_fn does not support axum handler functions, it is much more restrictive. Please can you open a separate question in the Q&A section?

jplatte avatar Aug 08 '24 17:08 jplatte