This is a short guide to help you get started. I'm going to use CGI, not FastCGI, but it's really the same thing. Just imagine the loop being around the parameter selection.
A simple CGI
Let's start with a simple CGI program. I will be using cgi_this to run it for lack of having a real web server handy.
#!/usr/bin/env perl
use strict;
use warnings;
use CGI;
my $q = CGI->new;
my $name = $q->param('name');
print $q->header;
if ($name) {
print <<"HTML";
<html><body><h1>Hello, $name</hi></body></html>
HTML
}
else {
print <<"HTML";
<html><body><form method="GET">
<label>What's your name? <input type="text" name="name"></label>
</form></body></html>
HTML
}
1;
This is hello.pl. It needs an executable flag.
Running the program
You start it with cgi_this as follows.
$ ls
hello.pl
$ cgi_this
Exporting '.', available at:
http://127.0.0.1:3000/
Found the following scripts:
http://127.0.0.1:3000/hello.pl
Now you can open it in the browser.

If you enter a name and submit the form, it will display a greeting.

Converting to PSGI
All of this is straight-forward. Now let's convert it.
We'll start with a new file named hello.psgi. It doesn't really matter if it's called .psgi, but this is the convention.
We have to do a couple of steps in order to make it work with the PSGI protocol. We will use Plack::Request to help us do that.
The entire program needs to be wrapped in a my $app = sub { ... }; call.
#!/usr/bin/env plackup
use strict;
use warnings;
use Plack::Request;
my $app = sub {
my $env = shift; # this is the Plack environment
my $req = Plack::Request->new($env);
my $q = CGI->new;
my $name = $q->param('name');
print $q->header;
if ($name) {
print <<"HTML";
<html><body><h1>Hello, $name</hi></body></html>
HTML
}
else {
print <<"HTML";
<html><body><form method="GET">
<label>What's your name? <input type="text" name="name"></label>
</form></body></html>
HTML
}
};
# no 1; here, we want it to return $app;
Now obviously we haven't loaded CGI, and there's no CGI environment anyway. So next we need to get the parameter. Get rid of the $q bit and use the $req instead.
my $name = $req->parameters->{name};
Now run this with plackup, then request it at http://localhost:5000.
$ plackup hello.psgi
HTTP::Server::PSGI: Accepting connections at http://0:5000/
<html><body><form method="GET">
<label>What's your name? <input type="text" name="name"></label>
</form></body></html>
Response should be array ref or code ref: 1 at ...
BANG! It fails, because we're not done yet. As you can see, it wrote the HTML to STDOUT, but that didn't go to the browser. That's because PSGI passes around references, and your program does not talk directly to STDOUT or STDERR.
It also complains about the missing reference. Let's deal with that first. At the end of the code reference, add this:
# prepare the response
my $res = $req->new_response(200);
$res->content_type('text/html');
return $res->finalize;
We're asking our Plack::Request to make a new Plack::Response for us, set a content type, and return the finalized (think immutable) response to the Plack handler, which will serialise and it to the browser as an actual HTTP response.
Now replace all the print statements. Make a new variable $content and instead of printing output, concatenate it to that variable. Then hand that to the response.
my $content;
if ($name) {
$content .= <<"HTML";
<html><body><h1>Hello, $name</hi></body></html>
HTML
}
else {
$content .= <<"HTML";
<html><body><form method="GET">
<label>What's your name? <input type="text" name="name"></label>
</form></body></html>
HTML
}
# prepare the response
my $res = $req->new_response(200);
$res->content_type('text/html');
$res->body($content);
Now restart your app in the terminal and access it again. It will look the same as the CGI.
