The joy of PSGI middleware

I must admit that I rarely feel comfortable with (web application) frameworks - each system facilitates a certain type of task but it complicates the missing parts. Good frameworks support extension via plugins, but each framework has its own plugin architecture to learn. That's why I like PSGI so much - it only specifies how to connect things. This is how PSGI looks like to me (image CC-BY-SA by CMG Lee):


Once you understand the PSGI specification you can build applications with existing bricks and create new bricks. Tatsuhiko Miyagawa has described using and creating Plack middleware in his 2009 advent calendar. The path of a request through a stack of middleware layers can be illustrated with an onion:


By now there are more than 200 PSGI middlewares classes at CPAN. An organized registry of PSGI middleware modules would help. I'd propose the following classification for the primary action that the middleware does to request and response flow:

  • middleware returns a response (e.g. Plack::Middleware::Static)
  • middleware passes request and response unchanged (e.g. Plack::Middleware::SimpleLogger)
  • middleware modifies the request (e.g. Plack::Middleware::Rewrite)
  • middleware modifies the response (e.g. Plack::Middleware::ETag)
  • middleware routes to different applications (e.g. Plack::Builder)

In my opinion a useful PSGI middleware should concentrate one one simple task instead of building yet another framework. In the last couple of days I added some middleware modules that can be used independently (like all middleware modules) or combined:

The source code of each module is rather short (around one third for code, documentation, and unit tests each) and the modules are quite new. Feedback is welcome, for instance github pull requests or comments how to further simplify.

What do you think about the "the shorter and more focused, the better" approach to creating PSGI middleware modules?


I wonder how you'd classify Plack::Middleware::Apache2::ModSSL in your system?

It doesn't modify the request or the response, but adds data to $env.

Leave a comment

About Jakob

user-pic Research & Development at a German library union network.