hyper/service/
service.rs

1use std::future::Future;
2
3/// An asynchronous function from a `Request` to a `Response`.
4///
5/// The `Service` trait is a simplified interface making it easy to write
6/// network applications in a modular and reusable way, decoupled from the
7/// underlying protocol.
8///
9/// # Functional
10///
11/// A `Service` is a function of a `Request`. It immediately returns a
12/// [`Future`] representing the eventual completion of processing the
13/// request. The actual request processing may happen at any time in the
14/// future, on any thread or executor. The processing may depend on calling
15/// other services. At some point in the future, the processing will complete,
16/// and the [`Future`] will resolve to a response or an error.
17///
18/// At a high level, the `Service::call` function represents an RPC request. The
19/// `Service` value can be a server or a client.
20///
21/// # Utilities
22///
23/// The [`hyper-util`][util] crate provides facilities to bridge this trait to
24/// other libraries, such as [`tower`][tower], which might provide their
25/// own `Service` variants.
26///
27/// See [`hyper_util::service`][util-service] for more information.
28///
29/// [tower]: https://docs.rs/tower
30/// [util]: https://docs.rs/hyper-util
31/// [util-service]: https://docs.rs/hyper-util/latest/hyper_util/service/index.html
32pub trait Service<Request> {
33    /// Responses given by the service.
34    type Response;
35
36    /// Errors produced by the service.
37    ///
38    /// Note: Returning an `Error` to a hyper server, the behavior depends on the
39    /// protocol. In most cases, hyper will cause the connection to be abruptly aborted.
40    /// It will abort the request however the protocol allows, either with some sort of RST_STREAM,
41    /// or killing the connection if that doesn't exist.
42    type Error;
43
44    /// The future response value.
45    type Future: Future<Output = Result<Self::Response, Self::Error>>;
46
47    /// Process the request and return the response asynchronously.
48    /// `call` takes `&self` instead of `mut &self` because:
49    /// - It prepares the way for async fn,
50    ///   since then the future only borrows `&self`, and thus a Service can concurrently handle
51    ///   multiple outstanding requests at once.
52    /// - It's clearer that Services can likely be cloned.
53    /// - To share state across clones, you generally need `Arc<Mutex<_>>`
54    ///   That means you're not really using the `&mut self` and could do with a `&self`.
55    ///   The discussion on this is here: <https://github.com/hyperium/hyper/issues/3040>
56    fn call(&self, req: Request) -> Self::Future;
57}
58
59impl<Request, S: Service<Request> + ?Sized> Service<Request> for &'_ S {
60    type Response = S::Response;
61    type Error = S::Error;
62    type Future = S::Future;
63
64    #[inline]
65    fn call(&self, req: Request) -> Self::Future {
66        (**self).call(req)
67    }
68}
69
70impl<Request, S: Service<Request> + ?Sized> Service<Request> for &'_ mut S {
71    type Response = S::Response;
72    type Error = S::Error;
73    type Future = S::Future;
74
75    #[inline]
76    fn call(&self, req: Request) -> Self::Future {
77        (**self).call(req)
78    }
79}
80
81impl<Request, S: Service<Request> + ?Sized> Service<Request> for Box<S> {
82    type Response = S::Response;
83    type Error = S::Error;
84    type Future = S::Future;
85
86    #[inline]
87    fn call(&self, req: Request) -> Self::Future {
88        (**self).call(req)
89    }
90}
91
92impl<Request, S: Service<Request> + ?Sized> Service<Request> for std::rc::Rc<S> {
93    type Response = S::Response;
94    type Error = S::Error;
95    type Future = S::Future;
96
97    #[inline]
98    fn call(&self, req: Request) -> Self::Future {
99        (**self).call(req)
100    }
101}
102
103impl<Request, S: Service<Request> + ?Sized> Service<Request> for std::sync::Arc<S> {
104    type Response = S::Response;
105    type Error = S::Error;
106    type Future = S::Future;
107
108    #[inline]
109    fn call(&self, req: Request) -> Self::Future {
110        (**self).call(req)
111    }
112}