What I’m doing with Catalyst
As I’m exploring the various things Catalyst can do, and following along with the tutorials and the Catalyst book from Packt Publishing, I’m going to write a little bit about it. I’m not sure if this is the appropriate place for this post, or if it would be better at Mark.Beihoffer.com (my personal blog) so I might be cross-posting this to both.
Basically, I wanted to develop a simple web application with Catalyst, but I didn’t want to copy the examples out of the tutorials (the “books” application is the one they use in the main Catalyst ten-chapter tutorial, and it’s fine, but I’ve already done it and besides, it’s already been done) verbatim. So, I decided to start with a simple database, since Catalyst creates a substantial portion of your Models and Schemas directly from your database tables.
The database I designed is still an ongoing project. Right now it has Users, Roles, Todos, and Addresses as the main tables. It also has tables such as UserRoles, TodoUsers, and UserAddress (these are not actually the table names; they are the object class names generated by Catalyst (and modified by yourself) from your database tables), which map Users to Roles, Todo items to Users, and Addresses to Users. This is known as Object-Relational Mapping, or ORM. It is called this because basically you are trying to solve the impedance mismatch between a Relational Database Management System and the Objects in the object-oriented software that you’re writing.
Basically, you want to be able to say something like
$todo->add_to_todo_users();
to save a TodoUser table row into the todo_user table, instead of something like this;
INSERT INTO todo_users (todo_id, user_id) VALUES (?, ?): '8', '1'
.
(I think the reasons why should be obvious, even to the casual observer.)
So far, Catalyst really does the trick for easing the pain of writing SQL statements by hand. The trouble is, you do need to become much better at writing Perl instead, particularly object-oriented Perl, which is a whole ‘nother ballgame. But I digress.
So, my simple application handles Users, their Roles in the system (right now you can be either an Admin or a User, or both), User’s Addresses (both home and work addresses are supported, like in the Packt Publishing Catalyst book’s sample application), and, most importantly for myself, User Todo’s.
Why are the Todo’s so important? Well, because I’ve got a lot To Do, and I’m constantly struggling to find a good solution for organizing all of those things. So, they’re important to me, I guess. Scratch your own itch, eat your own dog food, whatever.
Now, of course, I did get carried away and decided to make it a multi-user system. This is a design flaw, in retrospect, as it would probably have been like, waaaay easier, if I’d just made it a single-user system. But that’s not really the point, is it? Where’s the fun in writing a web application if it only supports one user?
Unless, of course, it’s Bamboo Invoice. But again, I digress.
So, it’s a multiple user application, with User Roles and Access Control Lists, or ACLs as they’re known, that handles an Addressbook and a Todo list for each user.
That’s all. Simple, really. But I want my first Catalyst application to be simple; it’s for exploring Catalyst, not trying to create the next Facebook or YouTube. That being said, however, it’s turning out that Catalyst scales up to the level where you could definitely write Facebook or YouTube in Catalyst (some minor performance/scalability issues aside.) How could I possibly make this bold claim? Well, because I just wrote a Catalyst application, and I only used 1/10th of Catalyst’s features, and an insignificantly small fraction of a percent of available Catalyst plugins and Perl modules.
One thing about my application that I am very pleased with is the ability for an Admin user to add normal Users through a web-based form. I am particularly proud of the fact that I was unhappy with how passwords were being stored in plain text in the database (thanks for providing me with ample nightmare material, Reddit and Slashdot and K5) instead of being stored as password hashes, as they always should be.
None of the tutorials or the book indicated how to do this, so I ended up having to integrate the Perl module Digest::SHA1 into my application in order to correctly generate password hashes, and then I needed to explore the HTML::FormFu Perl module (and Catalyst plugin) fairly in-depth in order to figure out how to extract the password from the form after it is submitted, create a hash from the password, and then save the new user object to the database, rather than having the user saved immediately upon form submission, which was why the passwords were being saved in plain old clear text. This was trickier than it sounds, but I eventually figured it out and wrote the necessary custom methods.
Which, speaking of HTML::FormFu, brings me to my next topic: how Catalyst provides you with multiple choices in terms of how you want to handle forms.
Although the last time I went through the tutorial they were using something called HTML::Widget, and this time they provide you with the choice of using either HTML::FormFu or FormBuilder, I eventually weighed all the available options I was aware of and decided to go with HTML::FormFu for the long term.
I won’t go into too much detail about how I reached this decision, but suffice it to say that HTML::Widget is now deprecated and will no longer be maintained, and that my experience with FormBuilder from the Packt book left a little to be desired, which lead me to HTML::FormFu as the One True Form Module and Catalyst Plugin of Which Little Besides the Kitchen Sink is Left to the Imagination.
The documentation for FormFu is substantial, to say the least. I’ve only scratched the surface with it, so far, but I’m impressed with the architecture of how the module is used so far; it works beautifully with Template Toolkit, which is the View portion of the MVC framework I’m using (I’m mostly using it because almost all the tutorials and book examples use TT; there are other options such as Mason, Petal, and, er, well, lots of options.) to render the site into HTML.
FormFu handles form validation for you, so you can just specify what kind of data you require in the form configuration file and it will automatically generate errors and ask the user to re-submit the form if they don’t fill it out correctly. This is obviously a huge improvement over writing laboriously lengthy regular expressions to check, for instance, if a valid email address has been submitted.
FormFu will also automatically populate your form with information from your database, which is wonderful if you’d like to be able to update database objects (can I call them database objects yet, or do I still have to call them table rows?) such as changing a User’s Address or whatnot.
It then does the form validation in accordance with your specifications, which are written in fairly simple configuration files along with the basic form layout. There are a wide variety of constraints to choose from, many of which I know absolutely nothing about, but I have high hopes for the future.
Finally, after the form has been submitted and validated, it is simply saved into your database with a simple method call. Easy, peasy! It really couldn’t get much easier than this.
One caveat: FormFu is officially Beta software, so the API is evolving and will probably break a few times before the 1.x release is out.
For my simple Todo-list and Addressbook application, this is fine. For your large, production web application, this may not be the case.
In fact, I have to hesitantly and somewhat reluctantly admit that Catalyst makes me a little bit nervous sometimes due to the enormous amount of dependencies involved. Hopefully as I progress as a Catalyst programmer this feeling will fade, but right now I’ve just seen too many rather abrupt changes in the Catalyst documentation (particularly the tutorials have significantly changed, recently) as well as the recommended Catalyst best practices and which modules and plugins to use, for instance.
Aside from that, I must admit that it’s been both challenging and fun to work on this application. I must emphasize that right now it’s only running on my laptop, and there is no real plan to release the code or have a site “go live” with the application running, because it’s still beta code (there are bugs, I’ll admit that much), and I also don’t want to jump the gun by releasing crap code, which this application very well may be (time will tell, I suppose.)
This may change, however. In the meantime, I’m going to go to bed dreaming about what *real* applications I could create with Catalyst, now that I’m gaining familiarity with the tools.
Catalyst is actually much more than a toolset; it’s a workbench, utility belt, Swiss Army scalpel, and
hydrogen fuel cell on wheels. Sometimes it’s a little bit overwhelming, what all it can do. I’m just trying to be patient and not be too frustrated with the seemingly slow pace of my progress with it.
October 22, 2008
Using Catalyst to Develop Web Applications
I’ve recently been honing my chops with Perl’s Catalyst framework; working my way through the tutorials, reading the module documentation, creating sample applications, and whatnot. The framework has a steep (for me, at least) learning curve, but I believe that overall it will improve my productivity and increase the maintainability of my web applications.
When you create a skeleton application, the framework installs the core MVC modules under your project directory, and it includes a web server built right in to the application, so you can launch the app right away without having to configure Apache’s mod_perl or fastcgi. It’s really nice to have the server open in a console window while you’re serving the site so you can see the stack trace and server responses while you’re browsing the site on the same system.
Catalyst also includes support for user authentication and authorization, so you can plug in those modules and get started on your application without having to worry about how you’re going to secure your application or get user logins working. It also supports form validation through the FormValidator plugin, which makes validating user input a breeze, which is an enormous timesaver over the old ways of doing form validation.
The manual is extensive, with a ten chapter tutorial included, so you can follow along and build the sample application yourself, which is quite helpful in understanding how the framework organizes all the files in your application. You can check the code for the tutorial out from a Subversion repository, which is nice if you’re not interested in doing a lot of typing.
I’m still learning Catalyst, so I’m not really the best person to ask about maintaining applications with it, but so far, it’s been fascinating to learn and I’m eager to get started on a live application soon for one of our new domains. We’ve just registered five more domain names, and I don’t know what we’re going to do with a few of them yet, but they’re registered for three years so hopefully we’ll have time to get a few things up and running, and I plan to use Catalyst to launch sites based on custom code.
Ruby on Rails, Django, Symfony, and CakePHP are all good alternatives to Catalyst, if Perl isn’t your language of choice, but as for myself, I personally have a lot invested in my Perl education and I’d like to be able to write web applications in the language I’m most comfortable with. I don’t mind PHP that much, so I tinkered with Symfony and CakePHP a bit this summer, and Ruby is very interesting to me, but I don’t have much experience with Ruby, so I think using Perl will be faster and more productive for me personally.
PHP is certainly a popular option these days, but I’m not a huge fan of it so far for serious coding, although I’m not opposed to giving it a shot now that PHP5 has decent object support built-in.
In short, Catalyst supplies the die-hard Perl coder with a great MVC framework similar to Ruby on Rails, with access to a large library of modules and plug-ins, and excellent flexibility in terms of what you decide to use for a Model. The tutorial uses SQLite for the examples, but MySQL and PostgreSQL are supported as well, and since the Model is abstracted out of the application, it should make it easy to change database back-ends if you don’t like SQLite or want to support multiple kinds of database for your application.
One thing I haven’t yet tried to accomplish is to get a Catalyst application running under an Apache VirtualHost, which would be ideal as that’s what we run on our web server. I’m sure it won’t be too problematic, but you never know. Perhaps that’s what I should do next, before I start coding an application in earnest, before I get to the stage of launching the application and realize I have no idea how to get it to run under Apache VirtualHosts.
Wish me luck!