Easy PSGI

When I write replies to questions on StackOverflow and places like that recommending that people abandon CGI programs in favour of something that uses PSGI, I often get some push-back from people claiming that PSGI makes things far too complicated.

I don’t believe that’s true. But I think I know why they say it. I think they say it because most of the time when we say “you should really port that code to PSGI” we follow up with links to Dancer, Catalyst or Mojolicious tutorials.

I know why we do that. I know that a web framework is usually going to make writing a web app far simpler. And, yes, I know that in the Plack::Request documentation, Miyagawa explicitly says:

Note that this module is intended to be used by Plack middleware developers and web application framework developers rather than application developers (end users).

Writing your web application directly using Plack::Request is certainly possible but not recommended: it’s like doing so with mod_perl’s Apache::Request: yet too low level.

If you’re writing a web application, not a framework, then you’re encouraged to use one of the web application frameworks that support PSGI (http://plackperl.org/#frameworks), or see modules like HTTP::Engine to provide higher level Request and Response API on top of PSGI.

And, in general, I agree with him wholeheartedly. But I think that when we’re trying to persuade people to switch to PSGI, these suggestions can get in the way. People see switching their grungy old CGI programs to a web framework as a big job. I don’t think it’s as scary as they might think, but I agree it’s often a non-trivial task.

Even without using a web framework, I think that you can get benefits from moving software to PSGI. When I’m running training courses on PSGI, I emphasise three advantages that PSGI gives you over other Perl web development environments.

  1. PSGI applications are easier to debug and test.
  2. PSGI applications can be deployed in any environment you want without changing a line of code.
  3. Plack Middleware

And I think that you can benefit from all of these features pretty easily, without moving to a framework. I’ve been thinking about the best way to do this and I think I’ve come up with a simple plan:

  • Change your shebang line to /usr/bin/plackup (or equivalent)
  • Put all of your code inside my $app = sub { ... }
  • Switch to using Plack::Request to access all of your input parameters
  • Build up your response output in a variable
  • At the end of the code, create and return the required Plack response (either using Plack::Response or just creating the correct array reference).

That’s all you need. You can drop your new program into your cgi-bin directory and it will just start working. You can immediately benefit from easier testing and later on, you can easily deploy your application in a different environment or start adding in middleware.

As an experiment to find how easy this was, I’ve been porting some old CGI programs. Back in 2000, I wrote three articles introducing CGI programming for Linux Format. I’ve gone back to those articles and converted the CGI programs to PSGI (well, so far I’ve done the programs from the first two articles – I’ll finish the last one in the next day or so, I hope).

It’s not the nicest of code. I was still using the CGI’s HTML generation functions back then. I’ve replaced those calls with HTML::Tiny. And they aren’t very complicated programs at all (they were aimed at complete beginners). But I hope they’ll be a useful guide to how easy it is to start using PSGI.

My programs are on Github. Please let me know what you think.

If you’re interested in modern Perl Web Development Techniques, you might find it useful to attend my upcoming two-day course on the subject.

Update: On Twitter, Miyagawa reminds me that you can use CGI::Emulate::PSGI or CGI::PSGI to run CGI programs under PSGI without changing them at all (or, at least, changing them a lot less than I’m suggesting here). And that’s what I’d probably do if I had a large amount of CGI code that I wanted to to move to PSGI quickly. But I still think it’s worth showing people that simple PSGI programs really aren’t any more complicated than simple CGI programs.

10 thoughts on “Easy PSGI

  1. I am not in the top flight of perl programmers but I ported an old old old CGI program (a SSO system) from old style cgi to plackup in a weekend. I hadn’t seen plack before that weekend, but after a couple of days work the program – which was being used as part of a load test environment – was up running hundreds of concurrent connections
    The plack documentation is really excellent and if you want to dig into the underlying plack programs they are easy to read too

  2. If you were to point someone at a ‘framework’, other than Mojolicious, Dancer, Catalyst then Twiggy might be an option.

    I am increasingly using this for micro-websites lately simply because it is so easy to set up and is blindingly fast.

  3. But how can we do this on a shared server? I don’t believe they offer plack. I’m always told I need to pay for a VPS if I want to install it myself. It really seems that shared hosts are an anchor that’s holding us back.

    1. Hi Debi,

      I can’t really argue with that. There will always be nasty cheap hosting companies that don’t offer decent support for modern programming practices. In fact, as I wrote last month, it’s likely that many of these cheap hosting companies already won’t have CGI.pm installed (if they’re using Centos 6 or later).

      I think we need to approach this in two ways:

      • Firstly, it would be great if some “official-sounding” Perl body produced information for these hosting companies explaining clearly the best way to support Perl web development. It’s really not hard – this stuff is already pre-packaged for all of the distributions that these companies use. This is something I’m currently thinking about
      • Secondly, I think people need to vote with their feet. If your hosting company doesn’t give you what you want, then find another one that does
    2. They don’t need to offer Plack. Your application can install any CPAN dependencies as long as they’re pure perl, by using local::lib or its equivalent and copy them all via FTP/rsync. Plack doesn’t have a mandatory C extension in its deps.

      That said, for such environments it would be even easier to actually choose a lightweight framework such as Mojolicious or Web::Simple, since they have even smaller dependencies. (Isn’t it ironic that using frameworks would have a fewer deps than using raw Plack at all?)

      And then to run the PSGI app you just created, on a shared server, you can use the CGI environment – don’t confuse with CGI.pm – you don’t need to use CGI.pm to run programs in a CGI environment. Plack offers a CGI handler that doesn’t have any non-core dependencies https://metacpan.org/source/MIYAGAWA/Plack-1.0039/lib/Plack/Handler/CGI.pm so you just copy the file into your lib path, then run Plack::Handler::CGI->new->run($app).

      What’s the benefit of converting your CGI.pm apps to PSGI and then run it again on CGI? You now have a better testability, power of Plack middleware, and then have a forward compatibility when you decide to move off of your shared host server: your code now doesn’t need to be modified at all, to run on your dedicated server with a standalone server such as Starman.

  4. I have also had much success with this pattern – Plack::Request is really easy to work with and not a million miles away from the cgi interface. Plack::Response is the CGI object you always wished you had – response headers are no longer set in stone as soon as you call $cgi->headers() and it’s really easy to subclass or encapsulate when you want to add features to the response object.

  5. “PSGI applications are easier to debug and test.”

    Could you please elaborate and provide an example?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.