-
Notifications
You must be signed in to change notification settings - Fork 173
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
AsyncAuthorizeRequest
should consider being replaced with a bounded tower::Service
#242
Comments
AsyncAuthorizeRequest
is very nearly Service
, needs poll_ready
AsyncAuthorizeRequest
needs poll_ready
Another downside to not having |
I'm curious what your use case is. Maybe just writing a custom middleware from scratch is easier? I'd like to avoid making |
I realized later after writing this issue that maybe I should just use a custom service impl. I initially saw I still do think there's an elegance in replacing |
AsyncAuthorizeRequest
needs poll_ready
AsyncAuthorizeRequest
should consider being replaced with a bounded tower::Service
So while I think there's nothing that needs to be done here, I am curious: would there be any downsides to having this (with a default implementation)? The existing implementations would then just leave the function defaulted while custom ones could do other things, right? |
I suppose not. |
I found a downside last night. The error type would need to be changed. The call to I'm still trying to figure out the right solution in my custom service that I'm converting my auth to. Right now I'm leaning to having an error type parameter that defaults to The other thought I'm considering is just having a structured error type that distinguishes between inner service errors and auth service errors, and then implementing The third thought I've had is to just either require the auth service to use |
Requiring the auth error type to be |
Oops, |
Bug Report
Version
tower-http v0.2.5
Crates
tower-http
Description
tower_http::auth::AsyncRequireAuthorization
uses a traitAsyncAuthorizeRequest
to define the authorization. This trait is very nearly a refinement oftower::Service
except it has no equivalent totower::Service::poll_ready()
. This means I can't easily implement async authorization in terms of an underlyingtower::Service
without manually checkingpoll_ready()
and blocking my future on that, despite the wrappingAsyncRequireAuthorization
itself advertising that it is ready. This breaks the whole ready tracking oftower::Service
.I think
AsyncAuthorizeRequest
needs its ownpoll_ready()
method. It can have a default implementation that just returnsPoll::Ready(Ok(()))
so as to preserve compatibility.AsyncRequireAuthorization
can then poll that in its ownpoll_ready()
. This way I can properly delay readiness until my wrapped service is ready.Beyond that, it would be nice to actually just go ahead and allow
tower::Service
impls with appropriate bounds inAsyncRequireAuthorization
, so I can use existing service combinators to construct something of the appropriate shape without having to define a custom type just for theAsyncAuthorizeRequest
impl. This could work by adding a blanket impl ofAsyncRequireAuthorization
for anyT: tower::Service
with the right shape1. This would be a breaking change though as it would produce an error for any type that already implements bothAsyncAuthorizeRequest
andtower::Service
. A nice benefit of this approach is I could then add arbitrary middleware to my auth implementation (such as tracing) or add additional validation with something liketower::ServiceExt::map_response()
or populating auth error response bodies withtower::ServiceExt::map_err()
.This could also be done in a backwards-compatible way by adding an adaptor that wraps a
tower::Service
and implementsAsyncAuthorizeRequest
(along with convenience methods onAsyncRequireAuthorization
andAsyncRequireAuthorizationLayer
), but this is a bit more awkward. This could be used as a transition plan until tower-http 0.3 though.Footnotes
This would admittedly be mildly odd on the naming front since
<T as Service>::Response
would actually be aRequest
and<T as Service>::Error
would be aResponse
but it should work just fine. ↩The text was updated successfully, but these errors were encountered: