Skip to content
New issue

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

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

Already on GitHub? # to your account

axum: allow body types other than axum::body::Body in Services passed to serve #3205

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

mladedav
Copy link
Collaborator

Motivation

A user in #3202 tried to use middlewares around the whole Router so that their layers run before routing happens. They ran into problems caused by their layers changing the Body type.

So far I've seen only the NormalizePathLayer used in this way which does not change the Body type so there were never issues. But I don't see a reason not to support this for other layers that do change the body, such as CompressionLayer.

Solution

This PR adds another generic parameter to Serve to keep track of the Response::Body type returned by the service provided.

There are no breaking changes as far as I can tell as inference knows the body type. This could break someone who for some reason names the type parameters explicitly. There is no rush with this and we may want to wait with this and release it in the next breaking release.

Alternatives

We may also choose not to support this. Users can just map the response body with .map_response_body(axum::body::Body::new) before callign serve. The price is just one box (and maybe a bit of ergonomics) as far as I can tell.


let app = ServiceBuilder::new()
.layer_fn(|_| tower::service_fn(|_| std::future::ready(Ok(Response::new(CustomBody)))))
.service(Router::<()>::new());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we add some routes, which type will be the body? The axum body type? Or CustomBody?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CustomBody. The layer returns a service which always returns that without even using the Router in this test.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add an handle to check if this works? Or are our handlers tight to our body implementation?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do that (in a few days).

The handler (and Router) would still return axum::body::Body, it's just the outer layer which changes that to something else.

@ttys3
Copy link
Contributor

ttys3 commented Feb 3, 2025

seems this PR is a reverse of #1751 (which is mainly to solve #1110 ) ?

@jplatte
Copy link
Member

jplatte commented Feb 3, 2025

This is not reverting anything from #1751. That was about the router being generic over the body. axum::serve did not exist back then.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants