11

Here's a Ruby poject that implements the middleware pattern. From the description, I have no idea what the pattern is, what it's useful for, and why other solutions wouldn't work as well.

What is the middleware pattern, and what are its advantages and drawbacks?

3
  • Good question; the project seems to assume a definition that has little to do with the common usage of the term Middleware. Jul 1, 2013 at 12:04
  • 2
    ...and that taking an existing term and slapping "pattern" on the end makes it something more than it actually is.
    – Blrfl
    Jul 1, 2013 at 12:11
  • based on the description given "responsible for calling the next middleware, and may modify the request along the way" - this seems to be a simplification of one of the GoF patterns, the Chain of Responsibility en.wikipedia.org/wiki/Chain-of-responsibility_pattern PHP frameworks like CakePHP & Laravel use middleware.
    – visualex
    Dec 29, 2019 at 20:16

4 Answers 4

8

Of course, the term middleware has changed quite a bit since this question has been posted (almost 5 years ago at the time I am writing this).

While reading the recently published book, Building Microservices With ASP.NET Core (by Kevin Hoffman) I came upon this term and wanted to know more about it.

That lead me to the Microsoft site which now defines it in the following way:

What is middleware?

Middleware is software that's assembled into an application pipeline to handle requests and responses. Each component:

  • Chooses whether to pass the request to the next component in the pipeline.
  • Can perform work before and after the next component in the pipeline is invoked.

The middleware pattern is often used as a way to describe how message routing is handled in a microservices system. Somewhat as a central Controller which decides which microservice will receive the incoming message. In this way it is a "middleware component" which handles message routing.

7

The author of the project you linked describes middleware as a "state engine" for business logic, akin to Windows Communication Foundation. That's not the usual definition for middleware (software that glues two or more heterogenous applications together), and I don't think the "middleware pattern" is really a thing.

I think the author is playing a bit fast and loose with his terminology.

6
  • 1
    Ooooh... I respectfully disagree as of 2016. What @robert-harvey said was probably true in 2013. A pattern is a known solution to a common problem. And if software pieces are written with the intent of allowing other pieces to be inserted in the workflow, it increases composability and flexibility. It is highly loosely coupled. This is the "O" in SOLID, the Open-Closed Principle at work. This is what my friends would definitely call the "Middleware Pattern".
    – Rap
    May 3, 2016 at 13:22
  • @rap: That's not what Middleware is. Middleware (things like Biztalk Server from Microsoft) is less relevant now than it ever was. Systems are still heterogenous, but they're glued together with common protocols like REST and JSON. May 3, 2016 at 15:07
  • 2
    I was talking about nodeJS express, passport, ... basically anything with a next() function. Like here. Does that change your response at all? Maybe we were misunderstanding each other?
    – Rap
    May 5, 2016 at 18:18
  • 1
    @Rap Apparently people use the word "middleware" to describe all sorts of things. It's certainly not a "software pattern." May 5, 2016 at 18:22
  • 1
    I think I had the same question a while back and what I found was that middleware is following the 'decorator' pattern Feb 13, 2019 at 21:19
4

Based on what I can tell from the example, it basically allows an arbitrary set of pre-action and post-action hooks that are chained in a defined way (hence, you build the stack it goes through) on a particular initial state of an input (in this case, nil, but there's no requirement for it to be such).

Their motivation appears to be in the context of HTTP requests where you might alter request/response properties in any given way. I don't think this pattern is overly useful in the general sense (and calling it "middleware" is certainly a misappropriation).

The advantage appears to be separation of concerns - e.g. something handles the generalized system for hooking and chaining operations to an input. Any subscription to this service could easily be deployed in other contexts and plugged right into a sequence of operations. It's also easy to guess the side effects of inserting any particular operation into the chain - as long as it's done statically.

The disadvantage to me would be that the context is completely removed - it's not clear what you're operating on without a strong naming convention or what the impact of any change to the subscribers is without understanding the context. You would have to put both the caller context and what it does into the naming convention in order to have it be understandable from both sides.

To me, it feels like it would be better to represent the operations as a whole concept; e.g. setting all properties in one spot. I can see the need for perhaps some portion of the application to inject properties and it's a much more interesting usage, for example, maybe in the context of an HTTP request you have something that changes the response type to XML while it's spitting out XML.

However, the way this is set up, you'd have to ensure that was the only spot setting the response type, the only one that will for a particular request, or just the last one which would overwrite any that came before it. Otherwise you'd run into issues.

I'm not sure that solving the problem this way is a compelling pattern, but I fully concede that might be because I looked at and thought about it for 30 minutes. I'm guessing somebody put more time than that into making it, so there could be things I'm missing.

4

I first came across the middleware 'pattern' in the node.js connect, and latter express, projects: it's just a clear and simple way of writing asynchronous code, where callbacks are slotted into an 'framework' API, each of which is expected to itself accept a callback parameter, which is to be executed when the routine is to return. In the context of connect, which is an HTTP server application framework, all parts of the request cycle and application logic can be implemented or accessed, with chained callbacks. Thus in this context, middleware is a self-contained unit of code that provides a service through a predefined API. It could be authentication and authorisation, request file-upload parsing, adjusting view data through an XSLT transform.... I suppose it follows the metaphor of the traditional use of the term, as described in an earlier answer.