ServiceBuilder

Struct ServiceBuilder 

Source
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>

Source

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>

Source

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);
Source

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);
Source

pub fn config<U>(self, config: U) -> ServiceBuilder<T, S, C, M>
where U: Send + Sync + 'static,

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);
Source

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);
Source

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);
Source

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);
Source

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);
Source

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§

Source§

impl<T: Debug, Serializer: Debug, Catch: Debug, Middleware: Debug> Debug for ServiceBuilder<T, Serializer, Catch, Middleware>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T, Serializer, Catch, Middleware> Freeze for ServiceBuilder<T, Serializer, Catch, Middleware>
where T: Freeze, Serializer: Freeze, Catch: Freeze, Middleware: Freeze,

§

impl<T, Serializer, Catch, Middleware> !RefUnwindSafe for ServiceBuilder<T, Serializer, Catch, Middleware>

§

impl<T, Serializer, Catch, Middleware> Send for ServiceBuilder<T, Serializer, Catch, Middleware>
where T: Send, Serializer: Send, Catch: Send, Middleware: Send,

§

impl<T, Serializer, Catch, Middleware> Sync for ServiceBuilder<T, Serializer, Catch, Middleware>
where T: Sync, Serializer: Sync, Catch: Sync, Middleware: Sync,

§

impl<T, Serializer, Catch, Middleware> Unpin for ServiceBuilder<T, Serializer, Catch, Middleware>
where T: Unpin, Serializer: Unpin, Catch: Unpin, Middleware: Unpin,

§

impl<T, Serializer, Catch, Middleware> !UnwindSafe for ServiceBuilder<T, Serializer, Catch, Middleware>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.