Create skeleton PSGI application for the SCO project

PSGI Plack::Request

I know it was short, but at this point I had enough from the testing. I like testing, but having lots of test withouth the real application (even if we are talking about a clone) looks pointless. Besides, I had doubts about the reusability of those tests, so instead of writing more tests, I switched gears, and started to write the web application.

I was wondering a bit which framework should I use for the project. The MetaCPAN Web is written using Catalyst. I know Dancer quite well. I have some experience with Mojolicious, but in the end I thought: Let's not use any of these. Let's start by implementing everything in plain PSGI. It is both a learning experience and at least at this point, the project does not need fancy things the frameworks might provide.

The first thing I wanted to create is a skeleton for the PSGI-based web application. Something simple like when we once started with PSGI, but with more robust layout.

So I created the >app.psgi file in the root of the project with the following content:

#!/usr/bin/perl
use strict;
use warnings;

use lib 'lib';
use MetaCPAN::SCO;

my $app = MetaCPAN::SCO->run;

Instead of implementing the application in the app.psgi file, I am going to implement it in the MetaCPAN::SCO module and call its run method.

The interesting part of the code is in the lib/MetaCPAN/SCO.pm file.

The run method creates, and implicitly returns a reference to a subroutine. (Assigning the anonymous subroution to the $app variable is not required here, but it will be useful later on.)

Inside the anonymous subroutine we create a Plack::Request object. Then using the path_info method we can retreive part of the requested URL that does not contain the name of the machine. Just the path from /. We can use this later to identify the various requests. (These are usually called "routes").

According to the specs of PSGI, this anonymous subroution needs to return an array reference with 3 values. The first one is the HTTP status code. 200 means success, 404 means "Not Found". The 2nd element is the header. In our case we return only the Content-type. When the path_info equals to '/' we return text/plain which means our response will be interpreted as plain text. In all other cases we return 404 - Not Found and the Content-Type is text/html. There is no particular reason for the differences. At this point the content (which is the string in the 3rd element of the array is plain text. So either Content-Type will work.

Later, when both will return HTML, we'll have to make sure that the Content-Type is text/html in both cases.

package MetaCPAN::SCO;
use strict;
use warnings;

use Plack::Request;

our $VERSION = '0.01';

=head1 NAME

SCO - search.cpan.org clone

=cut

sub run {
    my $app = sub {
        my $env = shift;

        my $request = Plack::Request->new($env);
        if ($request->path_info eq '/') {
            return [ '200', [ 'Content-Type' => 'text/plain' ], ['Hello'], ];
        }

        return [ '404', [ 'Content-Type' => 'text/html' ], ['404 Not Found'], ];
    };
}


1;

Once we have this, we can launch the web-application by running plackup in the root directory of the project. It will tell us we can browse to http://localhost:5000/. Try that, and try adding something to the end of the request to see the 404 error message.

To finish this change, we also need to add Plack::Request to the list of prerequisites. This is the change we make in the Makefile.PL:

    PREREQ_PM    => {
       'Plack::Request'   => '0',
    },
$ git add .
$ git commit -m "add app.psgi and some basic code to show a main page and to give 404 otherwise"

commit

Other pages

Start using Template Toolkit to show the empty pages
Serving static files such as favicon.ico and robots.txt using Plack
Create the search.cpan.org look and feel
Building an open source clone of search.cpan.org using the MetaCPAN API
Add "404 Not Found" page

Author

Gabor Szabo (szabgab) Gabor Szabo