Skip to main content

Service

Trait Service 

Source
pub trait Service<Req> {
    type Response;
    type Error;

    // Required method
    async fn call(
        &self,
        req: Req,
        ctx: ServiceCtx<'_, Self>,
    ) -> Result<Self::Response, Self::Error>;

    // Provided methods
    async fn ready(&self, ctx: ServiceCtx<'_, Self>) -> Result<(), Self::Error> { ... }
    async fn shutdown(&self) { ... }
    fn poll(&self, cx: &mut Context<'_>) -> Result<(), Self::Error> { ... }
    fn map<F, Res>(self, f: F) -> ServiceChain<Map<Self, F, Req, Res>, Req>
       where Self: Sized,
             F: Fn(Self::Response) -> Res { ... }
    fn map_err<F, E>(self, f: F) -> ServiceChain<MapErr<Self, F, E>, Req>
       where Self: Sized,
             F: Fn(Self::Error) -> E { ... }
}
Expand description

An asynchronous function from a Request to a Response.

The Service trait represents a request/response interaction, receiving requests and returning replies. Conceptually, a service is like a function with one argument that returns a result asynchronously:

async fn(Request) -> Result<Response, Error>

The Service trait generalizes this form. Requests are defined as a generic type parameter, while responses and other details are defined as associated types on the trait implementation. This design allows services to accept many request types and produce a single response type.

Services can also have internal mutable state that influences computation using Cell, RefCell, or Mutex. Services intentionally do not take &mut self to reduce overhead in common use cases.

Service provides a uniform API; the same abstractions can represent both clients and servers. Services describe only transformation operations, which encourages simple API surfaces, easier testing, and straightforward composition.

Services can only be called within a pipeline. The Pipeline enforces shared readiness for all services in the pipeline. To process requests from one service to another, all services must be ready; otherwise, processing is paused until that state is achieved.


struct MyService;

impl Service<u8> for MyService {
    type Response = u64;
    type Error = Infallible;

    async fn call(&self, req: u8, ctx: ServiceCtx<'_, Self>) -> Result<Self::Response, Self::Error> {
        Ok(req as u64)
    }
}

Sometimes it is not necessary to implement the Service trait. For example, the above service could be rewritten as a simple function and passed to fn_service.

async fn my_service(req: u8) -> Result<u64, Infallible>;

Service cannot be called directly, it must be wrapped to an instance of Pipeline or by using ctx argument of the call method in case of chanined services.

Required Associated Types§

Source

type Response

Responses given by the service.

Source

type Error

Errors produced by the service when polling readiness or executing call.

Required Methods§

Source

async fn call( &self, req: Req, ctx: ServiceCtx<'_, Self>, ) -> Result<Self::Response, Self::Error>

Processes a request and returns the response asynchronously.

The call method can only be invoked within a pipeline, which enforces readiness for all services in the pipeline. Implementations of call must not call ready; the ctx argument ensures the service is ready before it is invoked.

Provided Methods§

Source

async fn ready(&self, ctx: ServiceCtx<'_, Self>) -> Result<(), Self::Error>

Returns when the service is ready to process requests.

If the service is at capacity, ready will not return immediately. The current task is notified when the service becomes ready again. This function should be called while executing on a task.

Note: Pipeline readiness is maintained across all services in the pipeline. The pipeline can process requests only if every service in the pipeline is ready.

Source

async fn shutdown(&self)

Shuts down the service.

Returns when the service has been properly shut down.

Source

fn poll(&self, cx: &mut Context<'_>) -> Result<(), Self::Error>

Polls the service from the current async task.

The service may perform asynchronous computations or maintain asynchronous state during polling.

Source

fn map<F, Res>(self, f: F) -> ServiceChain<Map<Self, F, Req, Res>, Req>
where Self: Sized, F: Fn(Self::Response) -> Res,

Maps this service’s output to a different type, returning a new service.

This is similar to Option::map or Iterator::map, changing the output type of the underlying service.

This function consumes the original service and returns a wrapped version, following the pattern of standard library map methods.

Source

fn map_err<F, E>(self, f: F) -> ServiceChain<MapErr<Self, F, E>, Req>
where Self: Sized, F: Fn(Self::Error) -> E,

Maps this service’s error to a different type, returning a new service.

This is similar to Result::map_err, changing the error type of the underlying service. It is useful, for example, to ensure multiple services have the same error type.

This function consumes the original service and returns a wrapped version.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl<F, Pub, Ctl> Service<Io<F>> for ServerHandler<Pub, Ctl>

Source§

type Response = ()

Source§

type Error = ServerError<()>

Source§

async fn call( &self, req: Io<F>, _: ServiceCtx<'_, ServerHandler<Pub, Ctl>>, ) -> Result<<ServerHandler<Pub, Ctl> as Service<Io<F>>>::Response, <ServerHandler<Pub, Ctl> as Service<Io<F>>>::Error>

Source§

impl<Pub, Ctl> Service<IoBoxed> for ServerHandler<Pub, Ctl>

Source§

type Response = ()

Source§

type Error = ServerError<()>

Source§

async fn call( &self, io: IoBoxed, _: ServiceCtx<'_, ServerHandler<Pub, Ctl>>, ) -> Result<<ServerHandler<Pub, Ctl> as Service<IoBoxed>>::Response, <ServerHandler<Pub, Ctl> as Service<IoBoxed>>::Error>

Source§

impl<S, Req> Service<Req> for &S
where S: Service<Req>,

Source§

type Response = <S as Service<Req>>::Response

Source§

type Error = <S as Service<Req>>::Error

Source§

async fn ready( &self, ctx: ServiceCtx<'_, &S>, ) -> Result<(), <S as Service<Req>>::Error>

Source§

fn poll(&self, cx: &mut Context<'_>) -> Result<(), <S as Service<Req>>::Error>

Source§

async fn shutdown(&self)

Source§

async fn call( &self, request: Req, ctx: ServiceCtx<'_, &S>, ) -> Result<<&S as Service<Req>>::Response, <&S as Service<Req>>::Error>

Source§

impl<S, Req> Service<Req> for Box<S>
where S: Service<Req>,

Source§

type Response = <S as Service<Req>>::Response

Source§

type Error = <S as Service<Req>>::Error

Source§

async fn ready( &self, ctx: ServiceCtx<'_, Box<S>>, ) -> Result<(), <S as Service<Req>>::Error>

Source§

async fn shutdown(&self)

Source§

async fn call( &self, request: Req, ctx: ServiceCtx<'_, Box<S>>, ) -> Result<<Box<S> as Service<Req>>::Response, <Box<S> as Service<Req>>::Error>

Source§

fn poll(&self, cx: &mut Context<'_>) -> Result<(), <S as Service<Req>>::Error>

Implementors§

Source§

impl Service<Connect> for ntex::client::ConnectorService

Source§

impl Service<Control<H2Error>> for ntex::http::h2::DefaultControlService

Source§

impl<A, B, R> Service<R> for Then<A, B>
where A: Service<R>, B: Service<Result<<A as Service<R>>::Response, <A as Service<R>>::Error>, Error = <A as Service<R>>::Error>,

Source§

type Response = <B as Service<Result<<A as Service<R>>::Response, <A as Service<R>>::Error>>>::Response

Source§

type Error = <B as Service<Result<<A as Service<R>>::Response, <A as Service<R>>::Error>>>::Error

Source§

impl<A, B, Req> Service<Req> for AndThen<A, B>
where A: Service<Req>, B: Service<<A as Service<Req>>::Response, Error = <A as Service<Req>>::Error>,

Source§

type Response = <B as Service<<A as Service<Req>>::Response>>::Response

Source§

type Error = <A as Service<Req>>::Error

Source§

impl<A, F, Req, Res> Service<Req> for Map<A, F, Req, Res>
where A: Service<Req>, F: Fn(<A as Service<Req>>::Response) -> Res,

Source§

type Response = Res

Source§

type Error = <A as Service<Req>>::Error

Source§

impl<A, R, F, E> Service<R> for MapErr<A, F, E>
where A: Service<R>, F: Fn(<A as Service<R>>::Error) -> E,

Source§

impl<A, S> Service<Connect<A>> for SslConnectorService2<S>
where A: Address, S: Service<Connect<A>, Response = Io, Error = Error<ConnectError>>,

Source§

impl<A, S> Service<Connect<A>> for SslConnectorService<S>
where A: Address, S: Service<Connect<A>, Response = Io, Error = ConnectError>,

Source§

impl<A, S> Service<Connect<A>> for TlsConnectorService2<S>
where A: Address, S: Service<Connect<A>, Response = Io, Error = Error<ConnectError>>,

Source§

impl<A, S> Service<Connect<A>> for TlsConnectorService<S>
where A: Address, S: Service<Connect<A>, Response = Io, Error = ConnectError>,

Source§

impl<F, Err> Service<Control<F, Err>> for ntex::http::h1::DefaultControlService
where F: Filter, Err: ResponseError,

Source§

impl<F, Err> Service<WebRequest<Err>> for AppService<F, Err>
where F: Service<WebRequest<Err>, Response = WebRequest<Err>, Error = Err::Container>, Err: ErrorRenderer,

Source§

impl<F, Req, Res, Err> Service<Req> for FnService<F, Req>
where F: AsyncFn(Req) -> Result<Res, Err>,

Source§

type Response = Res

Source§

type Error = Err

Source§

impl<F, Req, Res, Err> Service<Req> for FnServiceFactory<F, Req, Res, Err, ()>
where F: AsyncFn(Req) -> Result<Res, Err>,

Source§

type Response = Res

Source§

type Error = Err

Source§

impl<F, S, B, C> Service<Io<F>> for H1ServiceHandler<F, S, B, C>
where F: Filter, C: Service<Control<F, S::Error>, Response = ControlAck<F>> + 'static, C::Error: Error, S: Service<Request> + 'static, S::Error: ResponseError, S::Response: Into<Response<B>>, B: MessageBody,

Source§

impl<F: Filter> Service<Io<F>> for WsTransportService

Source§

impl<F> Service<Io<F>> for SslAcceptorService
where F: Filter,

Source§

impl<F> Service<Io<F>> for TlsAcceptorService
where F: Filter,

Source§

impl<P, S, R> Service<R> for RetryService<P, S>
where P: Policy<R, S>, S: Service<R>,

Source§

type Response = <S as Service<R>>::Response

Source§

type Error = <S as Service<R>>::Error

Source§

impl<R, E, F> Service<R> for KeepAliveService<R, E, F>
where F: Fn() -> E,

Source§

impl<R, S> Service<R> for BufferService<R, S>
where S: Service<R> + 'static, R: 'static,

Source§

impl<Req, Err, F> Service<Req> for FnShutdown<Req, Err, F>
where F: AsyncFnOnce(),

Source§

type Response = Req

Source§

type Error = Err

Source§

impl<Req, Res, Err> Service<Req> for BoxService<Req, Res, Err>
where Req: 'static,

Source§

type Response = Res

Source§

type Error = Err

Source§

impl<Req, SLeft, SRight> Service<Req> for EitherService<SLeft, SRight>
where SLeft: Service<Req>, SRight: Service<Req, Response = <SLeft as Service<Req>>::Response, Error = <SLeft as Service<Req>>::Error>,

Source§

type Response = <SLeft as Service<Req>>::Response

Source§

type Error = <SLeft as Service<Req>>::Error

Source§

impl<S, Err> Service<WebRequest<Err>> for WebMiddleware<S, Err>
where S: Service<WebRequest<Err>, Response = WebResponse>, Err: ErrorRenderer, Err::Container: From<S::Error>,

Source§

impl<S, F, R> Service<R> for InspectErr<S, F>
where S: Service<R>, F: Fn(&<S as Service<R>>::Error),

Source§

type Response = <S as Service<R>>::Response

Source§

type Error = <S as Service<R>>::Error

Source§

impl<S, R> Service<R> for TimeoutService<S>
where S: Service<R>,

Source§

impl<S, Req> Service<Req> for PipelineSvc<S>
where S: Service<Req>,

Source§

type Response = <S as Service<Req>>::Response

Source§

type Error = <S as Service<Req>>::Error

Source§

impl<Svc, Req> Service<Req> for ServiceChain<Svc, Req>
where Svc: Service<Req>,

Source§

type Response = <Svc as Service<Req>>::Response

Source§

type Error = <Svc as Service<Req>>::Error

Source§

impl<T, R> Service<R> for InFlightService<T>
where T: Service<R>,

Source§

type Response = <T as Service<R>>::Response

Source§

type Error = <T as Service<R>>::Error

Source§

impl<T, R> Service<R> for OneRequestService<T>
where T: Service<R>,

Source§

type Response = <T as Service<R>>::Response

Source§

type Error = <T as Service<R>>::Error

Source§

impl<T, Req, F, In, Out, Err> Service<In> for Apply<T, Req, F, In, Out, Err>
where T: Service<Req>, F: AsyncFn(In, &ApplyCtx<'_, T>) -> Result<Out, Err>, Err: From<<T as Service<Req>>::Error>,

Source§

type Response = Out

Source§

type Error = Err

Source§

impl<T> Service<Connect<T>> for ConnectorService2<T>
where T: Address,

Source§

impl<T> Service<Connect<T>> for ntex::connect::ConnectorService<T>
where T: Address,

Source§

impl<V1, V2, V1R, V2R> Service<Variant2<V1R, V2R>> for VariantService2<V1, V2, V1R, V2R>
where V1: Service<V1R>, V2: Service<V2R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>,

Source§

type Response = <V1 as Service<V1R>>::Response

Source§

type Error = <V1 as Service<V1R>>::Error

Source§

impl<V1, V2, V3, V1R, V2R, V3R> Service<Variant3<V1R, V2R, V3R>> for VariantService3<V1, V2, V3, V1R, V2R, V3R>
where V1: Service<V1R>, V2: Service<V2R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V3: Service<V3R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>,

Source§

type Response = <V1 as Service<V1R>>::Response

Source§

type Error = <V1 as Service<V1R>>::Error

Source§

impl<V1, V2, V3, V4, V1R, V2R, V3R, V4R> Service<Variant4<V1R, V2R, V3R, V4R>> for VariantService4<V1, V2, V3, V4, V1R, V2R, V3R, V4R>
where V1: Service<V1R>, V2: Service<V2R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V3: Service<V3R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V4: Service<V4R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>,

Source§

type Response = <V1 as Service<V1R>>::Response

Source§

type Error = <V1 as Service<V1R>>::Error

Source§

impl<V1, V2, V3, V4, V5, V1R, V2R, V3R, V4R, V5R> Service<Variant5<V1R, V2R, V3R, V4R, V5R>> for VariantService5<V1, V2, V3, V4, V5, V1R, V2R, V3R, V4R, V5R>
where V1: Service<V1R>, V2: Service<V2R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V3: Service<V3R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V4: Service<V4R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V5: Service<V5R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>,

Source§

type Response = <V1 as Service<V1R>>::Response

Source§

type Error = <V1 as Service<V1R>>::Error

Source§

impl<V1, V2, V3, V4, V5, V6, V1R, V2R, V3R, V4R, V5R, V6R> Service<Variant6<V1R, V2R, V3R, V4R, V5R, V6R>> for VariantService6<V1, V2, V3, V4, V5, V6, V1R, V2R, V3R, V4R, V5R, V6R>
where V1: Service<V1R>, V2: Service<V2R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V3: Service<V3R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V4: Service<V4R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V5: Service<V5R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V6: Service<V6R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>,

Source§

type Response = <V1 as Service<V1R>>::Response

Source§

type Error = <V1 as Service<V1R>>::Error

Source§

impl<V1, V2, V3, V4, V5, V6, V7, V1R, V2R, V3R, V4R, V5R, V6R, V7R> Service<Variant7<V1R, V2R, V3R, V4R, V5R, V6R, V7R>> for VariantService7<V1, V2, V3, V4, V5, V6, V7, V1R, V2R, V3R, V4R, V5R, V6R, V7R>
where V1: Service<V1R>, V2: Service<V2R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V3: Service<V3R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V4: Service<V4R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V5: Service<V5R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V6: Service<V6R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V7: Service<V7R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>,

Source§

type Response = <V1 as Service<V1R>>::Response

Source§

type Error = <V1 as Service<V1R>>::Error

Source§

impl<V1, V2, V3, V4, V5, V6, V7, V8, V1R, V2R, V3R, V4R, V5R, V6R, V7R, V8R> Service<Variant8<V1R, V2R, V3R, V4R, V5R, V6R, V7R, V8R>> for VariantService8<V1, V2, V3, V4, V5, V6, V7, V8, V1R, V2R, V3R, V4R, V5R, V6R, V7R, V8R>
where V1: Service<V1R>, V2: Service<V2R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V3: Service<V3R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V4: Service<V4R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V5: Service<V5R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V6: Service<V6R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V7: Service<V7R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>, V8: Service<V8R, Response = <V1 as Service<V1R>>::Response, Error = <V1 as Service<V1R>>::Error>,

Source§

type Response = <V1 as Service<V1R>>::Response

Source§

type Error = <V1 as Service<V1R>>::Error