[][src]Struct tower_web::ServiceBuilder

pub struct ServiceBuilder<T, Serializer, Catch, Middleware> { /* fields omitted */ }

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

Methods

impl ServiceBuilder<(), DefaultSerializer, DefaultCatch, Identity>[src]

pub fn new() -> Self[src]

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

impl<T, S, C, M> ServiceBuilder<T, S, C, M>[src]

pub fn resource<U>(
    self,
    resource: U
) -> ServiceBuilder<<T as Chain<U>>::Output, S, C, M> where
    T: Chain<U>, 
[src]

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

pub fn serializer<U>(
    self,
    serializer: U
) -> ServiceBuilder<T, <S as Chain<U>>::Output, C, M> where
    S: Chain<U>, 
[src]

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

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

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

pub fn middleware<U>(
    self,
    middleware: U
) -> ServiceBuilder<T, S, C, <M as Chain<U>>::Output> where
    M: Chain<U>, 
[src]

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

pub fn catch<U>(self, catch: U) -> ServiceBuilder<T, S, U, M>[src]

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

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
[src]

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

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
[src]

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

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
[src]

Run the service in a non-blocking mode.

The returned Future object must be polled in order to process the incoming requests.

Trait Implementations

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

Auto Trait Implementations

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

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

Blanket Implementations

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T> From for T[src]

impl<T, U> TryFrom for T where
    U: Into<T>, 
[src]

type Error = !

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

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

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T> Same for T

type Output = T

Should always be Self

impl<T> Erased for T