November 10, 2008

What I’m doing with Catalyst

Filed under: Catalyst, Perl, Software Reviews — mbeihoffer @ 10:59 am

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.

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment