Tower Web — Expanding the middleware stack

tower-web version 0.2.2 has been released. It comes with a number of new features, which I will talk about in this post. Primarily, the middleware story is starting to come together. I will be expanding some on how middleware fits into Tower and web in general.

First, a quick recap

Tower is a library for writing modular and reusable networking services (previously announced here). It does this by defining a simple trait representing asynchronous request / response based services. It then provides a number of components that add functionality such as retries, load balancing, logging, etc.. all based around the Service trait.

Web services

Defining a web service with Tower Web is pretty straightforward. Here is a simple one:

Middleware

One great feature that comes from having a standardized Service trait is the ability to define middleware. Middleware is used to decorate the application, providing additional functionality.

  • Compress the response body, ideally without buffering the entire body up front.

The BufStream trait

To solve the problem of “what should the request and response bodies be bound by?”, Tower Web introduces a new trait: BufStream. The trait is an asynchronous stream of values that implement Buf (such a creative name).

The Middleware trait

As described above, a middleware is “just” a type that implements Service and dispatches the request to the inner service. We could build up our middleware stack like this:

  • LogMiddleware — Adds logging to the middleware stack.
  • ResponseFuture — If the middleware needs to see the response or take an action when the request has been handled.

Other new features

Middleware isn’t the only new thing. There have been two other changes of note.

Roadmap

There has been lots of good work to date and the work will continue. I wanted to close out this post with some thoughts on next steps.

Conclusion

I believe that the abstractions and implementations evolving out of Tower Web are promising and should help take the story for writing asynchronous services in Rust one step further. However, more validation is needed. We (the Rust community) must start pushing with real world applications.

I do stuff. I say stuff. It's serious business.