Friday, February 6, 2015

Why Write (OWIN) 'Middleware' in Web Applications?

TL;DR

Middleware - in the OWIN sense - can help you modularize your web application code, and maybe even enable you to reuse the plumbing code needed to deal with cross cutting concerns.

What is Middleware?

The context of this post is web applications, and in that context middlewares are pieces of code between the web server and the application code:


When a request comes in it is first handled by the web server, which hands it off to the first piece of middleware, which hands it to the next and so on until the request reaches the application code - i.e. the Nancy Modules or MVC/WebAPI controllers. The response takes the opposite route from the application, through the middlewares and the web server. You can think of that as a pipeline. The pipeline starts and ends with the web server, has the middlewares along the way and the application in the middle:


The trick here is that the middlewares all conform to the same interface; meaning that the pipeline be composed in many different ways - we may omit middleware 3, insert a 4th between 1 and 2 or swap 2 and 3.


Put Cross Cutting Concerns In Middleware

When we look at the handling of an HTTP request as a pipeline there are some things that we can immediately see that we could stick into that pipeline and thereby have applied to all requests. The obvious examples are request and response logging, perfomance logging and authentication. Indeed these are things that there are OSS OWIN middleware implementations for.
Slightly less obvious maybe are the more application specific things like request throttling, caching, redirects of obsoleted URLs, or even things like integration to a payment gateway.
The common theme of these candidates for middleware is they are moving concerns that should otheriwse have been handled by the application code out into the pipeline. This not only cleans up application code but also lends you the flexibility of the pipeline to re-configure the cross cutting stuff in one pipeline across all end points.


Middleware in a Service Oriented Architecture

I'm usually wary of the promise of reuse, but it does depend on where the reuse happens. There is usually not a whole lot of reuse of business logic between applications. But the frameworks they are built on are hugely reused. Middleware sits (well) in the middle.
In the case of service oriented architecture (where HTTP is use for inter-service communication) serving one or more applications there is a potential for reuse across services of the types of plumbing that are specific to this particular architecture but not to each individual service. Things like

  • adding monitoring endpoints to each service (middleware can short circuit the pipeline such that requests never reach the application)
  • collecting usage data
  • opening and closing database sessions
  • keeping track of correlation tokens
  • caching rules
  • ...

These are all examples of things that you don't want to write for every single service, but that you might want every service to have. The more services there are and the smaller each one is the more important the reuse of plumbing becomes. Wrapping each of these cross cutting pieces of functionality into middleware which plugs right into the pipeline makes them readily reusable across services.

OWIN and ASP.NET 5

Both OWIN and ASP.NET 5 supports the idea of middleware. In OWIN it's one the central features. In ASP.NET 5 the same feature is available 1) because ASP.NET 5 supports OWIN and 2) because it also brings it's own notion of middleware to the table.

In future post I'll dig more into both OWIN middleware and the 'proprietary' ASP.NET 5 middleware.