An Introduction to Application Development with Catalyst and Perl
Catalyst is the latest in the evolution of open-source Web development frameworks. Written in modern Perl and inspired by many of the projects that came before it, including Ruby on Rails, Catalyst is elegant, powerful and refined. It's a great choice for creating any Web-based application from the simple to the very complex.
Like many other popular Perl-based projects, Catalyst has a strong focus on flexibility and choice. Catalyst is especially powerful because it provides an abundance of features and the core environment, structure and interfaces on which virtually anything can be built without forcing you to do things in any particular way.
Writing applications in Catalyst is fast too. Just because you can tackle any aspect of application design yourself, doesn't mean you have to. Catalyst provides a wide array of refined, high-level, drop-in solutions to all kinds of problems and needs without limiting access to the nuts and bolts. Templating, ORM, authentication, automatic session management and all the other high-level features you'd want from a Web framework are available in Catalyst—and more.
Catalyst's approach is to provide these high-level features as optional plugins and modules. This is one of the greatest strengths of Perl—a tremendous number of refined modules and libraries are available. So, instead of re-inventing all this functionality, Catalyst provides a framework to bring together seamlessly what already exists.
Catalyst is bigger than itself—it is also everything that's available in CPAN. That alone makes it one of the most feature-rich frameworks there are.
In this article, I provide an introduction to Catalyst and how to use it for rapid application development. I cover the basics of how to create and lay out a new application as well as how to write the actions that will handle requests. I explain how to define flexible URL dispatch logic and some of the APIs that are available. I focus on the fundamentals, but I cover some of the popular available components as well, such as Template::Toolkit. I also talk about how you can extend Catalyst itself, and how you can deploy an application with Apache.
Background Knowledge and the MVC Architecture
Catalyst and Catalyst applications are written in Perl, so some basic Perl knowledge is necessary to use Catalyst effectively. You also should have some experience with object-oriented programming concepts, such as classes, methods, inheritance and so on.
Like Rails, Django, CakePHP and many other Web frameworks, Catalyst follows the venerable Model-View-Controller architectural pattern. MVC is a proven approach to structuring and segmenting application code for efficiency, flexibility and maintainability.
Plenty of tutorials and resources are available for MVC, so I won't spend too much time covering it here. If you've worked with other Web frameworks, chances are you're already familiar with MVC. If not, the most important thing to understand is that it is more about best practices than anything else.
The focus of this article is to explain the core details of how Catalyst operates, but since Catalyst made most of its layout decisions according to MVC, you'll still see it along the way.
Before you can install Catalyst on your system, you obviously need Perl. Most Linux distros already have Perl installed out of the box, but if not, install it with your package manager.
Catalyst itself is a Perl library that you can install with cpan:
The previous command installs Catalyst with development tools along with its many dependencies. For production/hosting systems that will run only applications without the need for development tools, you can install the smaller Catalyst::Runtime bundle instead.
Because Catalyst has so many dependencies, it can take quite a while to install on a fresh system. By default, CPAN asks if it should install each dependency individually, which can become redundant really quick. You can configure CPAN not to ask, but instead, I usually just cheat by holding down Enter for a few seconds to queue up a bunch of default ("yes, install the module!") keystroke/answers.
If the install fails on the first attempt, don't fret. Whatever the problem
may be, it probably will be explained in the scrollback along with what to
do to solve it. Typically, this involves nothing more than
installing/upgrading another module that wasn't automatically in the
dependency tree for whatever reason, or just running the
cpan command a
Catalyst Application Layout
Every Catalyst application is a Perl module/library/bundle—exactly like the modules on CPAN. This consists of a package/class namespace and standard structure of files and directories. The Catalyst::Devel package comes with a helper script to create new "skeleton" applications and to initialize the files and directories for you. For example, to create a new application called KillerApp, run the following:
This creates a new application structure at KillerApp/ with the following subdirectories:
lib/: this is the Perl include directory that stores all the Perl classes (aka packages or modules) for the application. This is added to the Perl lib path at runtime, and the directory structure corresponds to the package/class namespaces. For example, the two classes that are initially created have the following namespaces and corresponding file paths:
KillerApp — lib/KillerApp.pm
KillerApp::Controller::Root — lib/KillerApp/Controller/Root.pm
These directories also are created but initially are empty:
script/: this contains application-specific scripts, including the development server (killerapp_server.pl) that you can use to run the application in its own standalone Web server, as well as scripts to deploy the application in a "real" Web server. The helper script killerapp_create.pl creates new model, view and controller component classes.
t/: this is where "tests" go. If you follow a test-driven development process, for every new feature you write, you also will write an automated test case. Tests let you quickly catch regressions that may be introduced in the future. Writing them is a good habit to get into, but that's beyond the scope of this article.
The created skeleton application is already fully functional, and you can run it using the built-in test server:
cd KillerApp/ script/killerapp_server.pl
This fires up the app in its own dedicated Web server on port 3000. Open http://localhost:3000/ to see the default front page, which initially displays the Catalyst welcome message.
The Request/Response Cycle
All Web applications handle requests and generate responses. The fundamental job of any Web framework/platform/environment is to provide a useful structure to manage this process. Although there are different ways of going about this—from elegant MVC applications to ugly, monolithic CGI scripts—ultimately, they're all doing the same basic thing:
Decide what to call when a request comes in.
Supply an API for generating the response.
In Catalyst, this happens in special methods called "actions". On every request, Catalyst identifies one or more actions and calls them with special arguments, including a reference to the "context" object that provides a convenient and practical API through which everything else is accomplished.
Actions are contained within classes called "controllers", which live in a special path/namespace in the application (lib/KillerApp/Controller/). The skeleton application sets up one controller ("Root"), but you can create more with the helper script. For example, this creates a new controller class KillerApp::Controller::Something:
script/killerapp_create.pl controller Something
The only reason to have more than one controller is for organization; you can put all your actions in the Root controller with no loss of features or ability. Controllers are just the containers for actions.
In the following sections, I describe how Catalyst decides which actions to call on each request ("dispatch") and then explain how to use the supplied context object within them.