Struct ServiceBuilder
struct ServiceBuilder<L> { ... }
Declaratively construct Service values.
ServiceBuilder provides a builder-like interface for composing
layers to be applied to a Service.
Service
A Service is a trait representing an asynchronous function of a request
to a response. It is similar to async fn(Request) -> Result<Response, Error>.
A Service is typically bound to a single transport, such as a TCP
connection. It defines how all inbound or outbound requests are handled
by that connection.
Order
The order in which layers are added impacts how requests are handled. Layers
that are added first will be called with the request first. The argument to
service will be last to see the request.
# // this (and other) doctest is ignored because we don't have a way
# // to say that it should only be run with cfg(feature = "...")
# use Service;
# use ServiceBuilder;
#
# async
In the above example, the buffer layer receives the request first followed
by concurrency_limit. buffer enables up to 100 request to be in-flight
on top of the requests that have already been forwarded to the next
layer. Combined with concurrency_limit, this allows up to 110 requests to be
in-flight.
# use Service;
# use ServiceBuilder;
#
# async
The above example is similar, but the order of layers is reversed. Now,
concurrency_limit applies first and only allows 10 requests to be in-flight
total.
Examples
A Service stack with a single layer:
# use Service;
# use ServiceBuilder;
#
# use ConcurrencyLimitLayer;
#
# async
A Service stack with multiple layers that contain rate limiting,
in-flight request limits, and a channel-backed, clonable Service:
# use Service;
# use ServiceBuilder;
# use Duration;
#
# async
Implementations
impl ServiceBuilder<tower_layer::Identity>
const fn new() -> SelfCreate a new
ServiceBuilder.
impl<L> ServiceBuilder<L>
fn layer<T>(self: Self, layer: T) -> ServiceBuilder<Stack<T, L>>Add a new layer
Tinto theServiceBuilder.This wraps the inner service with the service provided by a user-defined
Layer. The provided layer must implement theLayertrait.fn option_layer<T>(self: Self, layer: Option<T>) -> ServiceBuilder<Stack<crate::util::Either<T, Identity>, L>>Optionally add a new layer
Tinto theServiceBuilder.# use Duration; # use Service; # use ServiceBuilder; # use TimeoutLayer; # asyncfn layer_fn<F>(self: Self, f: F) -> ServiceBuilder<Stack<crate::layer::LayerFn<F>, L>>Add a
Layerbuilt from a function that accepts a service and returns another service.See the documentation for
layer_fnfor more details.fn buffer<Request>(self: Self, bound: usize) -> ServiceBuilder<Stack<crate::buffer::BufferLayer<Request>, L>>Buffer requests when the next layer is not ready.
This wraps the inner service with an instance of the
Buffermiddleware.fn concurrency_limit(self: Self, max: usize) -> ServiceBuilder<Stack<crate::limit::ConcurrencyLimitLayer, L>>Limit the max number of in-flight requests.
A request is in-flight from the time the request is received until the response future completes. This includes the time spent in the next layers.
This wraps the inner service with an instance of the
ConcurrencyLimitmiddleware.fn load_shed(self: Self) -> ServiceBuilder<Stack<crate::load_shed::LoadShedLayer, L>>Drop requests when the next layer is unable to respond to requests.
Usually, when a service or middleware does not have capacity to process a request (i.e.,
poll_readyreturnsPending), the caller waits until capacity becomes available.LoadShedimmediately responds with an error when the next layer is out of capacity.This wraps the inner service with an instance of the
LoadShedmiddleware.fn rate_limit(self: Self, num: u64, per: std::time::Duration) -> ServiceBuilder<Stack<crate::limit::RateLimitLayer, L>>Limit requests to at most
numper the given duration.This wraps the inner service with an instance of the
RateLimitmiddleware.fn retry<P>(self: Self, policy: P) -> ServiceBuilder<Stack<crate::retry::RetryLayer<P>, L>>Retry failed requests according to the given retry policy.
policydetermines which failed requests will be retried. It must implement theretry::Policytrait.This wraps the inner service with an instance of the
Retrymiddleware.fn timeout(self: Self, timeout: std::time::Duration) -> ServiceBuilder<Stack<crate::timeout::TimeoutLayer, L>>Fail requests that take longer than
timeout.If the next layer takes more than
timeoutto respond to a request, processing is terminated and an error is returned.This wraps the inner service with an instance of the
timeoutmiddleware.fn filter<P>(self: Self, predicate: P) -> ServiceBuilder<Stack<crate::filter::FilterLayer<P>, L>>Conditionally reject requests based on
predicate.predicatemust implement thePredicatetrait.This wraps the inner service with an instance of the
Filtermiddleware.fn filter_async<P>(self: Self, predicate: P) -> ServiceBuilder<Stack<crate::filter::AsyncFilterLayer<P>, L>>Conditionally reject requests based on an asynchronous
predicate.predicatemust implement theAsyncPredicatetrait.This wraps the inner service with an instance of the
AsyncFiltermiddleware.fn map_request<F, R1, R2>(self: Self, f: F) -> ServiceBuilder<Stack<crate::util::MapRequestLayer<F>, L>> where F: FnMut(R1) -> R2 + CloneMap one request type to another.
This wraps the inner service with an instance of the
MapRequestmiddleware.Examples
Changing the type of a request:
use ServiceBuilder; use ServiceExt; # # asyncModifying the request value:
use ServiceBuilder; use ServiceExt; # # asyncfn map_response<F>(self: Self, f: F) -> ServiceBuilder<Stack<crate::util::MapResponseLayer<F>, L>>Map one response type to another.
This wraps the inner service with an instance of the
MapResponsemiddleware.See the documentation for the
map_responsecombinator for details.fn map_err<F>(self: Self, f: F) -> ServiceBuilder<Stack<crate::util::MapErrLayer<F>, L>>Map one error type to another.
This wraps the inner service with an instance of the
MapErrmiddleware.See the documentation for the
map_errcombinator for details.fn map_future<F>(self: Self, f: F) -> ServiceBuilder<Stack<crate::util::MapFutureLayer<F>, L>>Composes a function that transforms futures produced by the service.
This wraps the inner service with an instance of the
MapFutureLayermiddleware.See the documentation for the
map_futurecombinator for details.fn then<F>(self: Self, f: F) -> ServiceBuilder<Stack<crate::util::ThenLayer<F>, L>>Apply an asynchronous function after the service, regardless of whether the future succeeds or fails.
This wraps the inner service with an instance of the
Thenmiddleware.This is similar to the
map_responseandmap_errfunctions, except that the same function is invoked when the service's future completes, whether it completes successfully or fails. This function takes theResultreturned by the service's future, and returns aResult.See the documentation for the
thencombinator for details.fn and_then<F>(self: Self, f: F) -> ServiceBuilder<Stack<crate::util::AndThenLayer<F>, L>>Executes a new future after this service's future resolves. This does not alter the behaviour of the
poll_readymethod.This method can be used to change the
Responsetype of the service into a different type. You can use this method to chain along a computation once the service's response has been resolved.This wraps the inner service with an instance of the
AndThenmiddleware.See the documentation for the
and_thencombinator for details.fn map_result<F>(self: Self, f: F) -> ServiceBuilder<Stack<crate::util::MapResultLayer<F>, L>>Maps this service's result type (
Result<Self::Response, Self::Error>) to a different value, regardless of whether the future succeeds or fails.This wraps the inner service with an instance of the
MapResultmiddleware.See the documentation for the
map_resultcombinator for details.fn into_inner(self: Self) -> LReturns the underlying
Layerimplementation.fn service<S>(self: &Self, service: S) -> <L as >::Service where L: Layer<S>Wrap the service
Swith the middleware provided by thisServiceBuilder'sLayer's, returning a newService.fn service_fn<F>(self: Self, f: F) -> <L as >::Service where L: Layer<crate::util::ServiceFn<F>>Wrap the async function
Fwith the middleware provided by thisServiceBuilder'sLayers, returning a newService.This is a convenience method which is equivalent to calling
ServiceBuilder::servicewith aservice_fn, like this:# use ; # async # let _ = ;Example
use Duration; use ; # # asyncfn check_clone(self: Self) -> Self where Self: CloneCheck that the builder implements
Clone.This can be useful when debugging type errors in
ServiceBuilders with lots of layers.Doesn't actually change the builder but serves as a type check.
Example
use ServiceBuilder; let builder = new // Do something before processing the request .map_request // Ensure our `ServiceBuilder` can be cloned .check_clone // Do something after processing the request .map_response;fn check_service_clone<S>(self: Self) -> Self where L: Layer<S>, <L as >::Service: CloneCheck that the builder when given a service of type
Sproduces a service that implementsClone.This can be useful when debugging type errors in
ServiceBuilders with lots of layers.Doesn't actually change the builder but serves as a type check.
Example
use ServiceBuilder; # # ; # let builder = new // Do something before processing the request .map_request // Ensure that the service produced when given a `MyService` implements . // Do something after processing the request .map_response;fn check_service<S, T, U, E>(self: Self) -> Self where L: Layer<S>, <L as >::Service: Service<T, Response = U, Error = E>Check that the builder when given a service of type
Sproduces a service with the given request, response, and error types.This can be useful when debugging type errors in
ServiceBuilders with lots of layers.Doesn't actually change the builder but serves as a type check.
Example
use ServiceBuilder; use ; use ; // An example service ; ; ; ; ; let builder = new // At this point in the builder if given a `MyService` it produces a service that // accepts `Request`s, produces `Response`s, and fails with `Error`s . // Wrap responses in `WrappedResponse` .map_response // Now the response type will be `WrappedResponse` .;fn boxed<S, R>(self: Self) -> ServiceBuilder<Stack<tower_layer::LayerFn<fn(_: <L as >::Service) -> crate::util::BoxService<R, <<L as >::Service as Service<R>>::Response, <<L as >::Service as Service<R>>::Error>>, L>> where L: Layer<S>, <L as >::Service: Service<R> + Send + 'static, <<L as >::Service as Service<R>>::Future: Send + 'staticThis wraps the inner service with the
Layerreturned byBoxService::layer().See that method for more details.
Example
use ; use Duration; # # ; # ; # let service: = new .boxed .load_shed .concurrency_limit .timeout .service_fn; # let service = assert_service; # # where S:fn boxed_clone<S, R>(self: Self) -> ServiceBuilder<Stack<tower_layer::LayerFn<fn(_: <L as >::Service) -> crate::util::BoxCloneService<R, <<L as >::Service as Service<R>>::Response, <<L as >::Service as Service<R>>::Error>>, L>> where L: Layer<S>, <L as >::Service: Service<R> + Clone + Send + 'static, <<L as >::Service as Service<R>>::Future: Send + 'staticThis wraps the inner service with the
Layerreturned byBoxCloneService::layer().This is similar to the
boxedmethod, but it requires thatSelfimplementClone, and the returned boxed service implementsClone.See
BoxCloneServicefor more details.Example
use ; use Duration; # # ; # ; # let service: = new .boxed_clone .load_shed .concurrency_limit .timeout .service_fn; # let service = assert_service; // The boxed service can still be cloned. service.clone; # # where S:
impl Default for ServiceBuilder<tower_layer::Identity>
fn default() -> Self
impl<L> Freeze for ServiceBuilder<L>
impl<L> RefUnwindSafe for ServiceBuilder<L>
impl<L> Send for ServiceBuilder<L>
impl<L> Sync for ServiceBuilder<L>
impl<L> Unpin for ServiceBuilder<L>
impl<L> UnwindSafe for ServiceBuilder<L>
impl<L: $crate::clone::Clone> Clone for ServiceBuilder<L>
fn clone(self: &Self) -> ServiceBuilder<L>
impl<L: fmt::Debug> Debug for ServiceBuilder<L>
fn fmt(self: &Self, f: &mut fmt::Formatter<'_>) -> fmt::Result
impl<S, L> Layer for ServiceBuilder<L>
fn layer(self: &Self, inner: S) -> <Self as >::Service
impl<T> Any for ServiceBuilder<L>
fn type_id(self: &Self) -> TypeId
impl<T> Borrow for ServiceBuilder<L>
fn borrow(self: &Self) -> &T
impl<T> BorrowMut for ServiceBuilder<L>
fn borrow_mut(self: &mut Self) -> &mut T
impl<T> CloneToUninit for ServiceBuilder<L>
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8)
impl<T> From for ServiceBuilder<L>
fn from(t: T) -> TReturns the argument unchanged.
impl<T> Instrument for ServiceBuilder<L>
impl<T> ToOwned for ServiceBuilder<L>
fn to_owned(self: &Self) -> Tfn clone_into(self: &Self, target: &mut T)
impl<T> WithSubscriber for ServiceBuilder<L>
impl<T, U> Into for ServiceBuilder<L>
fn into(self: Self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom for ServiceBuilder<L>
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto for ServiceBuilder<L>
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>