|Perl Monk, Perl Meditation|
Serving Dynamic Content with Plackby Logicus
|on Oct 24, 2011 at 04:51 UTC||Need Help??|
In the first two parts of this serise of articles ("meet joe plack" and "serving static content with plack") on PSGI/Plack I introduced the concept of PSGI and provided some simple patterns to wet your appetite for it. Now in this 3rd part, I am going to introduce some more concepts and show how to begin using Plack to serve dynamic content.
In part two, I used the module Plack::Builder to 'mount', various paths and bind them to apps based on Plack::App::File in order to serve up static content.
This is all well and good, and nicely implements a powerful static content server in PSGI.Plack::Middleware
In order to make this more useful and to generate dynamic content, you will need to become familiar with the concept of Plack Middleware. In a nutshell, Plack Middleware components take a standard PSGI input, do some processing and then give a standard PSGI output, and thus Middleware components can be layered or stacked in a manner emulating Ruby's Rack system.
So what's going on here then? Well first of all, we have now added a new sub called "action", which returns a basic html skeleton displaying the current time. Also, we have now mounted "/" to another instance of builder, which enables the Plack Middleware component called ContentLength (Plack::Middleware::ContentLength). This component takes the PSGI output of $action, calculates it's length and sets the appropriate response header.
Setup like this, all requests which don't start with "/images", "/css", "/js", of "/favicon.ico", will be routed to the $action sub, and will result in the browser showing the same page with the current time on it.More Middleware
There are many middleware components available, and it is beyond the scope of this tut to go into them and describe them all so I am just going to show you a couple more and make some notes about layering them correctly before I sign off.
We have now added 2 more Middleware components to the stack; Debug which adds a nifty collapsable panel to the right hand side of the browser display, and Session which of course gives access to a neat and secure session management system. (More about that later)
You may notice that the two new components have extra arguments compared to the ContentLength component. These extra arguments are passed to the Middleware component and modify it's behaviour. In this case we are telling Session to use the non-volatile file storage method of holding it's data, and we are telling the Debug component that we want to see two panels in it's display; Memory usage and a performance TimerStacking order
It's important to think about the logical order of the stack as you are building it. For instance, we put ContentLength at the top because we want the ContentLength component to be the LAST component to be run prior to output. This is so that the Content-Length header is correct. If we were to enable it in the wrong position, and a later component was to modify the length of the document, the header would be incorrect and may cause rendering errors on some browsers.
Now because we changed the order, the ContentLength is going to be calculated before the Debug Panel is added to the output, which may result in the debug panel not being visible at all.
Ok that's all for now folks, In the next article I am going to start looking in more depth at the actual content generation phase and in using any values generated by the Middleware in your app.
Have a good one!