<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Jakob</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/jakob/" />
    <link rel="self" type="application/atom+xml" href="http://blogs.perl.org/users/jakob/atom.xml" />
    <id>tag:blogs.perl.org,2009-11-03:/users/jakob//1553</id>
    <updated>2012-09-28T12:31:56Z</updated>
    <subtitle>A blog about the Perl programming language</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.38</generator>

<entry>
    <title>The joy of PSGI middleware</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/jakob/2012/09/the-joy-of-psgi-middleware.html" />
    <id>tag:blogs.perl.org,2012:/users/jakob//1553.3894</id>

    <published>2012-09-28T09:05:00Z</published>
    <updated>2012-09-28T12:31:56Z</updated>

    <summary>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...</summary>
    <author>
        <name>Jakob</name>
        <uri>http://jakoblog.de</uri>
    </author>
    
    <category term="psgi" label="psgi" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/jakob/">
        <![CDATA[<p>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 <a href="http://plackperl.org">PSGI</a> so much - it only specifies how to connect things. This is how PSGI looks like to me (image <a href="http://commons.wikimedia.org/wiki/File:Lego_dimensions.svg">CC-BY-SA by CMG Lee</a>):</p>

<p><img alt="lego_dimensions.png" src="http://blogs.perl.org/users/jakob/2012/09/27/lego_dimensions.png" width="500" height="250" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></p>
]]>
        <![CDATA[<p>Once you understand <a href="http://search.cpan.org/perldoc?PSGI">the PSGI specification</a> you can build applications with existing bricks and create new bricks. Tatsuhiko Miyagawa has described <a href="http://advent.plackperl.org/2009/12/day-10-using-plack-middleware.html">using</a> and <a href="http://advent.plackperl.org/2009/12/day-23-write-your-own-middleware.html">creating</a> Plack middleware in his 2009 advent calendar. The path of a request through a stack of middleware layers can be illustrated with an onion:</p>

<p><img alt="middleware-onion.png" src="http://blogs.perl.org/users/jakob/2012/09/28/middleware-onion.png/500px-MiddlewareOnion.svg.png" width="500" height="407" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></p>

<p>By now there are <a href="https://metacpan.org/search?q=Plack%3A%3AMiddleware%3A%3A">more than 200 PSGI</a> 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:</p>

<ul>
<li><strong>↩</strong> middleware returns a response (e.g. Plack::Middleware::Static)</li>
<li><strong>⇄</strong> middleware passes request and response unchanged (e.g. Plack::Middleware::SimpleLogger)</li>
<li><strong>⇸</strong> middleware modifies the request (e.g. Plack::Middleware::Rewrite)</li>
<li><strong>⇷</strong> middleware modifies the response (e.g. Plack::Middleware::ETag)</li>
<li><strong>⇶</strong> middleware routes to different applications (e.g.  Plack::Builder)</li>
</ul>

<p>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:</p>

<ul>
<li><a href="http://search.cpan.org/perldoc?Plack::Middleware::Auth::AccessToken">Plack::Middleware::Auth::AccessToken</a> (↩) - Authentification via OAuth Bearer Token</li>
<li><a href="http://search.cpan.org/perldoc?Plack::Middleware::Negotiate">Plack::Middleware::Negotiate</a> (⇸, ⇶) - HTTP Content negotiation</li>
<li><a href="http://search.cpan.org/perldoc?Plack::Middleware::JSONP::Headers">Plack::Middleware::JSONP::Headers</a> (⇷) - Wrap HTTP Headers in JSON response, <a href="http://developer.github.com/v3/#json-p-callbacks">as implemented in github API</a></li>
<li><a href="http://search.cpan.org/perldoc?Plack::Middleware::SuppressResponseCodes">Plack::Middleware::SuppressResponseCodes</a> (⇷) - Set HTTP Status code 200 for errors</li>
<li><a href="http://search.cpan.org/perldoc?Plack::Middleware::REST">Plack::Middleware::REST</a> - (⇶,↩) Route or reject requests based on CRUDL verbs</li>
</ul>

<p>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. </p>

<p>What do you think about the "the shorter and more focused, the better" approach to creating PSGI middleware modules?</p>
]]>
    </content>
</entry>

</feed>
