pub struct ServiceBuilder<T, Serializer, Catch, Middleware> { /* private fields */ }Expand description
Configure and build a web service.
ServiceBuilder collects all the components and configuration required to
build the HTTP service. Once the service is defined, it can be run
with run.
§Examples
Defining a service with a single resource;
use tower_web::ServiceBuilder;
struct MyResource;
impl_web! {
impl MyResource {
// ...
}
}
ServiceBuilder::new()
.resource(MyResource)
.run(&addr);Defining a service with a multiple resources;
use tower_web::ServiceBuilder;
struct MyResource1;
struct MyResource2;
struct MyResource3;
impl_web! {
impl MyResource1 {
// ...
}
impl MyResource2 {
// ...
}
impl MyResource3 {
// ...
}
}
ServiceBuilder::new()
.resource(MyResource1)
.resource(MyResource2)
.resource(MyResource3)
.run(&addr);Defining a middleware stack
use tower_web::ServiceBuilder;
struct MyResource;
impl_web! {
impl MyResource {
// ...
}
}
ServiceBuilder::new()
.resource(MyResource)
.middleware(FooMiddleware::new("foo"))
.middleware(BarMiddleware::new("bar"))
.run(&addr);Implementations§
Source§impl ServiceBuilder<(), DefaultSerializer, DefaultCatch, Identity>
impl ServiceBuilder<(), DefaultSerializer, DefaultCatch, Identity>
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new ServiceBuilder with default configuration.
At least one resource must be added before building the service.
§Examples
use tower_web::ServiceBuilder;
struct MyResource;
impl_web! {
impl MyResource {
// ...
}
}
ServiceBuilder::new()
.resource(MyResource)
.run(&addr);Source§impl<T, S, C, M> ServiceBuilder<T, S, C, M>
impl<T, S, C, M> ServiceBuilder<T, S, C, M>
Sourcepub fn resource<U>(
self,
resource: U,
) -> ServiceBuilder<<T as Chain<U>>::Output, S, C, M>where
T: Chain<U>,
pub fn resource<U>(
self,
resource: U,
) -> ServiceBuilder<<T as Chain<U>>::Output, S, C, M>where
T: Chain<U>,
Add a resource to the service.
Resources are prioritized based on the order they are added to the
ServiceBuilder. If two resources handle the same route, then the one
that was added first gets priority.
§Examples
use tower_web::ServiceBuilder;
struct MyResource;
impl_web! {
impl MyResource {
// ...
}
}
ServiceBuilder::new()
.resource(MyResource)
.run(&addr);Sourcepub fn serializer<U>(
self,
serializer: U,
) -> ServiceBuilder<T, <S as Chain<U>>::Output, C, M>where
S: Chain<U>,
pub fn serializer<U>(
self,
serializer: U,
) -> ServiceBuilder<T, <S as Chain<U>>::Output, C, M>where
S: Chain<U>,
Add a serializer to the service.
Serializers convert response structs to bytes. Each given serializer handles a specific content-type. A service may have many registered serializers, each handling different content-types.
By default, the service is able to respond with “text/plain” and “application/json” bodies. Adding new serializers adds the ability to handle additional formats.
Currently, the only other supported format is “text/html” and is provided by the handlebars serializer. In future releases, third party crates will be able to provide serializer implementations.
§Examples
use tower_web::ServiceBuilder;
use tower_web::view::Handlebars;
struct MyResource;
#[derive(Response)]
#[web(template = "index")]
struct Index {
title: &'static str,
}
impl_web! {
impl MyResource {
#[get("/")]
fn index(&self) -> Result<Index, ()> {
Ok(Index {
title: "hello world",
})
}
}
}
ServiceBuilder::new()
.serializer(Handlebars::new())
.resource(MyResource)
.run(&addr);Sourcepub fn config<U>(self, config: U) -> ServiceBuilder<T, S, C, M>
pub fn config<U>(self, config: U) -> ServiceBuilder<T, S, C, M>
Add a config to the service.
Configs may be retrieved by their type and used from within extractors.
§Examples
use tower_web::ServiceBuilder;
use tower_web::extract::{Extract, Context, Immediate};
use tower_web::util::BufStream;
struct MyResource;
struct MyConfig {
foo: String
}
struct MyParam {
bar: String
}
impl<B: BufStream> Extract<B> for MyParam {
type Future = Immediate<MyParam>;
fn extract(context: &Context) -> Self::Future {
let config = context.config::<MyConfig>().unwrap();
let param = MyParam { bar: config.foo.clone() };
Immediate::ok(param)
}
}
impl_web! {
impl MyResource {
#[get("/")]
fn action(&self, param: MyParam) -> Result<String, ()> {
Ok(param.bar)
}
}
}
ServiceBuilder::new()
.resource(MyResource)
.config(MyConfig { foo: "bar".to_owned() })
.run(&addr);Sourcepub fn middleware<U>(
self,
middleware: U,
) -> ServiceBuilder<T, S, C, <M as Chain<U>>::Output>where
M: Chain<U>,
pub fn middleware<U>(
self,
middleware: U,
) -> ServiceBuilder<T, S, C, <M as Chain<U>>::Output>where
M: Chain<U>,
Add a middleware to the service.
Middleware that are defined last will receive requests first. In other
words, when a middleware is added to the ServiceBuilder, it will wrap
all previous middeware and all resources.
§Examples
use tower_web::ServiceBuilder;
struct MyResource;
impl_web! {
impl MyResource {
// ...
}
}
ServiceBuilder::new()
.resource(MyResource)
.middleware(FooMiddleware::new("foo"))
.middleware(BarMiddleware::new("bar"))
.run(&addr);Sourcepub fn catch<U>(self, catch: U) -> ServiceBuilder<T, S, U, M>
pub fn catch<U>(self, catch: U) -> ServiceBuilder<T, S, U, M>
Add a global catch handler.
In the event that a resource responds to a request with an error, the catch handler has an opportunity to convert that error to a response. Most of the time, the catch handler is used to convert the error to a friendy response status.
§Examples
extern crate http;
use tower_web::ServiceBuilder;
struct MyResource;
impl_web! {
impl MyResource {
// ...
}
}
ServiceBuilder::new()
.resource(MyResource)
.catch(|_: &http::Request<()>, error: tower_web::Error| {
assert!(error.status_code() == http::StatusCode::NOT_FOUND);
let response = http::response::Builder::new()
.status(404)
.header("content-type", "text/plain")
.body("where you at?")
.unwrap();
Ok(response)
})
.run(&addr);Sourcepub fn build_new_service<RequestBody>(
self,
) -> NewWebService<T::Resource, C::Catch, M>where
T: IntoResource<S, RequestBody>,
S: Serializer,
C: IntoCatch<S>,
M: HttpMiddleware<RoutedService<T::Resource, C::Catch>>,
RequestBody: BufStream,
pub fn build_new_service<RequestBody>(
self,
) -> NewWebService<T::Resource, C::Catch, M>where
T: IntoResource<S, RequestBody>,
S: Serializer,
C: IntoCatch<S>,
M: HttpMiddleware<RoutedService<T::Resource, C::Catch>>,
RequestBody: BufStream,
Build a NewWebService instance
The returned value impements tower_service::NewService and is used to
generate service::WebService values. usually, a NewWebService
instance is used to generate one service per TCP connection established
to the server.
§Examples
use tower_web::ServiceBuilder;
use tower_service::{Service, NewService};
use futures::Future;
struct MyResource;
impl_web! {
impl MyResource {
// ...
}
}
let new_service = ServiceBuilder::new()
.resource(MyResource)
.build_new_service();
// Use `new_service` to get an instance of our web service.
let mut service = new_service.new_service()
.wait().unwrap();
// Issue a request to the service
let request = http::request::Builder::new()
.method("POST")
.uri("/hello")
.body("hello".to_string())
.unwrap();
let response = service.call(request);Sourcepub fn run(self, addr: &SocketAddr) -> Result<()>where
T: IntoResource<S, LiftReqBody>,
S: Serializer,
C: IntoCatch<S> + Send + 'static,
C::Catch: Send,
M: HttpMiddleware<RoutedService<T::Resource, C::Catch>, RequestBody = LiftReqBody> + Send + 'static,
M::Service: Send,
<M::Service as HttpService>::Future: Send,
M::ResponseBody: Send,
<M::ResponseBody as BufStream>::Item: Send,
T::Resource: Send + 'static,
<T::Resource as Resource>::Buf: Send,
<T::Resource as Resource>::Body: Send,
<T::Resource as Resource>::Future: Send,
pub fn run(self, addr: &SocketAddr) -> Result<()>where
T: IntoResource<S, LiftReqBody>,
S: Serializer,
C: IntoCatch<S> + Send + 'static,
C::Catch: Send,
M: HttpMiddleware<RoutedService<T::Resource, C::Catch>, RequestBody = LiftReqBody> + Send + 'static,
M::Service: Send,
<M::Service as HttpService>::Future: Send,
M::ResponseBody: Send,
<M::ResponseBody as BufStream>::Item: Send,
T::Resource: Send + 'static,
<T::Resource as Resource>::Buf: Send,
<T::Resource as Resource>::Body: Send,
<T::Resource as Resource>::Future: Send,
Run the service
This builds the service and passes it to Hyper to run.
Note that Hyper requires all types to be Send. Thus, for this to work,
all resources must have response types that are Send.
use tower_web::ServiceBuilder;
struct MyResource;
impl_web! {
impl MyResource {
// ...
}
}
ServiceBuilder::new()
.resource(MyResource)
.run(&addr);Sourcepub fn serve<I>(self, incoming: I) -> impl Future<Item = (), Error = ()>where
I: ConnectionStream,
I::Item: Send + 'static,
T: IntoResource<S, LiftReqBody>,
S: Serializer,
C: IntoCatch<S> + Send + 'static,
C::Catch: Send,
M: HttpMiddleware<RoutedService<T::Resource, C::Catch>, RequestBody = LiftReqBody> + Send + 'static,
M::Service: Send,
<M::Service as HttpService>::Future: Send,
M::ResponseBody: Send,
<M::ResponseBody as BufStream>::Item: Send,
T::Resource: Send + 'static,
<T::Resource as Resource>::Buf: Send,
<T::Resource as Resource>::Body: Send,
<T::Resource as Resource>::Future: Send,
pub fn serve<I>(self, incoming: I) -> impl Future<Item = (), Error = ()>where
I: ConnectionStream,
I::Item: Send + 'static,
T: IntoResource<S, LiftReqBody>,
S: Serializer,
C: IntoCatch<S> + Send + 'static,
C::Catch: Send,
M: HttpMiddleware<RoutedService<T::Resource, C::Catch>, RequestBody = LiftReqBody> + Send + 'static,
M::Service: Send,
<M::Service as HttpService>::Future: Send,
M::ResponseBody: Send,
<M::ResponseBody as BufStream>::Item: Send,
T::Resource: Send + 'static,
<T::Resource as Resource>::Buf: Send,
<T::Resource as Resource>::Body: Send,
<T::Resource as Resource>::Future: Send,
Run the service in a non-blocking mode.
The returned Future object must be polled in order to process the incoming requests.
Trait Implementations§
Auto Trait Implementations§
impl<T, Serializer, Catch, Middleware> Freeze for ServiceBuilder<T, Serializer, Catch, Middleware>
impl<T, Serializer, Catch, Middleware> !RefUnwindSafe for ServiceBuilder<T, Serializer, Catch, Middleware>
impl<T, Serializer, Catch, Middleware> Send for ServiceBuilder<T, Serializer, Catch, Middleware>
impl<T, Serializer, Catch, Middleware> Sync for ServiceBuilder<T, Serializer, Catch, Middleware>
impl<T, Serializer, Catch, Middleware> Unpin for ServiceBuilder<T, Serializer, Catch, Middleware>
impl<T, Serializer, Catch, Middleware> !UnwindSafe for ServiceBuilder<T, Serializer, Catch, Middleware>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more