I have this one day Moose class I’ve developed. I was supposed to give it at YAPC, but I was sick and cancelled my trip.

Here’s the class summary I wrote for YAPC:

This will be an interactive hands-on course all about Moose. Moose is an OO system for Perl 5 that provides a simple declarative layer of “sugar” on top of a powerful, extensible meta-model.

With Moose, simple classes can be created without writing any subroutines, and complex classes can be simplified. Moose’s features include a powerful attribute declaration system, type constraints and coercions, method modifiers (“before”, “after”, and “around”), a role system (like mixins on steroids), and more. Moose also has a vibrant ecosystem of extensions as seen in the variety of MooseX:: modules on CPAN.

This course will cover Moose’s core features, dip a toe into the meta-model, and if there’s time, explore some of the more powerful MooseX:: modules available on CPAN

Students are expected to bring a laptop, as you will be writing code during the class. You will also be provided with a tarball a week or so before the class is scheduled, which will contain a directory tree skeleton and test files.

The class ended up being taught by Shawn Moore, and I got a lot of good feedback about the class slides and exercises.

I’d really like to give the class myself, and I am trying to figure out if there’s interest in the Twin Cities, MN area. I’d reserve a conference room at a hotel or on the UMN campus in Minneapolis or St Paul for the class, and I’m hoping to do this some time in August or September.

Normally, a one-day training session like this would run about $500 per person, but since this would be my first time actually giving the class, the rate would be a mere $120 per person.

In return, I want each attendee to commit to answering a short survey I’ll give them after the class so I can get feedback on the class and my teaching. So there is a small price for the discount ;)

In order to make this happen, I’d need at least 5 people to sign up.

If you have questions, feel free to ask in a comment or email me or email the Minneapolis Perl Mongers list.

If you’re interested in attending, please let me know what days of the week are best. Would you prefer a weekday, Saturday, or Sunday? Or maybe it doesn’t matter. Again, leave a comment or email me.

If there is enough interest, I’ll schedule it and then announce it on this blog and Minneapolis Perl Mongers list.

I’ve been working on web applications for a long time, and over the years I’ve developed a specific approach to structuring web application code. In the past few years, this has been strongly influenced by REST concepts.

My approach leads me to make use of some existing concepts, like cookies and sessions, in an idiosyncratic way. Sometimes in discussions about web application I’ll refer to these idiosyncrasies, but seen in isolation they may make no sense to anyone but me.

This entry will attempt to explain both my philosophical approach, and the practical consequences of that approach. This will not be a start-to-finish guide to building a web app (not even close).

Each Action Does One Thing

In this context, an action is a Catalyst action. In non-Catalyst speak, it’s a method that handles the response for a request. With REST, a request is identified by both its URI and its method, so we distinguish between a GET and POST to the same URI.

So what is one thing? That one thing can be one or more related database changes, some other non-database task (sending an email), or generating output for the client (HTML or something else).

An importance consequence of this “one thing” rule is that an action can either change some state on the server or return data to the client. An action never does both (ignoring side effects like logging or stats tracking). For a browser, this means that all non-GET requests are followed by a redirect to a GET.

I cannot abide an application that receives a POST, updates the database, and then returns some HTML. Inevitably, this produces crufty code filled with conditionals.

The worst examples of this are applications that have a single URI that displays a form, and then on a successful form submission display a different page at the same URI. This is a huge violation of REST, and makes the code even more crufty with conditionals.

I think the main reason people like to combine POST/PUT/DELETE handling and HTML generation is to make it easier to give feedback to the user. If the submission is unsuccessful, we want to show the same form to the user with some error messages (“password is required”). When the submisson is successful we want to give them feedback about that (“your comment has been accepted and is pending review”).

Of course, providing clear feedback to users is absolutely crucial in building a usable application, but we can have our RESTful, well-designed cake and eat it too.

RESTful, Minimal Sessions

Contrary to some of what you might read online, you can have sessions with REST. The key is that the URI must describe the whole item being requested, including the session. That means putting the session in the URI.

But putting sessions in the URI has all sorts of well-known problems. First, it makes for ugly URIs. Second, it means you have to carry that session URI throughout the application. Third, it makes session-jacking much easier.

The second problem is easy to address. Just don’t carry the session URI throughout the application! A properly built web application does not need a session for every request. If you just use the session to carry a response to a POST/PUT/DELETE, you can limit the scope of the session. I only need to include a session in the URI as part of a redirect, so my HTML pages never include links with a session.

To that end, I keep my sessions extremely minimal. There are only three things I put in a session:

  1. Error messages – these can be either general messages like “you don’t have access to edit comments” or specific to a form field like “this is not a valid email address”.
  2. Feedback messages – “your comment has been submitted for review”
  3. Form data – when a form submission results in an error, you show the form to the user again, and always make sure to repopulate it with the data they submitted.

All of this data shares the quality of being transient. It only needs to be used on a single URI. Once the user leaves the page in question, we no longer need the session.

This helps address the ugly URI problem. Most URIs just don’t have a session, so we limit the scope of our ugliness.

This also helps address the session-jacking problem. Again, the data is transient, and is only needed on one page. Since I don’t store authentication information in the session, you still need to authenticate to see the relevant page. This means that if the user gives the URI with a session to someone else, it doesn’t matter.

In my applications, sessions expire after five minutes. If a user tries to go back to an old URI with a session, then the application simply redirects them to the session-less URI, which is always valid, because my applications have Cool, RESTful URIs, except for the session piece.

Taken together, this lets me have RESTful sessions with no security risk and minimal ugliness.

As a bonus, keeping sessions minimal helps force me to think clearly about application workflow, rather than just jamming tons of data into a session and using it all over the application.

RESTful Cookie Authentication

Much of the literature on REST suggests that in order to be properly RESTful, you need to use HTTP authentication. Of course, anyone who’s ever worked on a real web application knows that HTTP authentication is a horrible, horrible thing to deal with. You have no control over the UI, it’s impossible to logout except with insane hacks, and it makes for an overall horrible user experience.

Realistically, if your client is a web browser, you have to use a cookie for authentication. Many applications, however, use a session cookie. Every request involves a session lookup, and the user id is stored in the session. This is bad and wrong. First, it requires that we have a session on every page, which I don’t like. Second, it egregiously violates RESTful principles by passing around an opaque token with unclear semantics.

For me, using an authentication-only cookie is close enough to REST. With an authentication cookie, we get an effect very similar to HTTP authentication. Every request includes the authentication information, and the server checks this on every request. There is no hidden state, and while this is still technically opaque, the opaque piece is as minimal as possible.

This still isn’t really RESTful, but I just don’t care. I’m all for doing things in an architecturally proper manner, but only if I can provide a great user experience too. Mostly, REST and a great experience are compatible, but when it comes to authentication, HTTP auth is simply not tenable.

However, I can at least minimize the degree to which I compromise, and using the cookie for authentication and authentication only is as minimal as I can get.

Practical Consequences

These approaches, taken together, have led me to write several Catalyst plugins and/or adopt others. First of all, I use Catalyst::Action::REST. I’m primarily interested in using it to let me dispatch GET, PUT, POST, and DELETE to different controller methods internally, and it does this very cleanly.

I also use my own Catalyst::Request::REST::ForBrowsers module. This lets me define all of my internal code in terms of the four HTTP methods mentioned above, but yet still work with browsers. Browsers have two problems. First, they don’t accept arbitrary document types, so I can’t return a well-defined document type of my choosing, I have to return HTML, and that HTML needs to include (by reference) information about styling (CSS) and client-side behavior (Javascript). This is fundamentally unlike a notional smart REST client. Second, browsers do not support PUT or DELETE, so I “tunnel” that through a POST.

I also use the Catalyst Session plugin, along with Catalyst::Plugin::Session::State::URI. I make sure to configure the URI state plugin to only rewrite redirects, as mentioned earlier.

Yesterday, I released Catalyst::Plugin::Session::AsObject. THis enforces session discipline by providing the session as an object, not a hash reference. Instead of writing $c->session()->{errors}, I write $c->session_object()->errors(). This makes it easy to limit what data can go in the session, and gives me a much nicer API for pulling data back out. Note that all the plugin does is let you configure the class name of the session object. You can provide your own class on a per-application basis, meaning you can use it for any session data you want, not just my three items.

For authentication, I use my own Catalyst::Plugin::AuthenCookie. When I wrote this, the dominant Catalyst Authentication plugin required that the user authentication be stored in a session. Since I did not want a session on every request, I ended up writing my own plugin. Since that time, the original Authentication plugin has made use of the session has optional, but I still find it dauntingly complex for common use, so I’ll stick with my own plugin.

So that’s a slice of my approach to web applications. Hopefully this was interesting, and less confusing than hearing about it piecemeal. It may also help explain why I’ve written some of my modules, in case anyone was wondering “what use is X”.

It occurred to me today that if you look at my history as a CPAN author, you’ll see that I’ve either written or heavily participated in every popular target of re-invention on CPAN!

I started off by writing an ORM, Alzabo. Back when I released it, this was one of the very first ORMs for Perl. Amusingly, I re-invented the whole ORM concept pretty much independently. I don’t think I even heard the term until after Alzabo was released.

(Class::DBI was also released around the same time, and became much more popular.)

Of course, if you do enough database programming in an OO language, an ORM is an obvious concept to “invent”, and that probably explains why there’s so damn many of them. People “invent” them before they realize that there are dozens already out there.

I’ve also worked on a templating system, Mason. In fact, before that, I wrote a mini-templating system at Digital River, where I worked with Ken Williams. Fortunately, Ken pointed me at Mason before I could get too far into my own, which was a good thing.

Mason is also a (primitive) webapp framework, so I’ve worked on one of those too, as well as providing an odd patch or two to Catalyst and various Catalyst plugins.

Then there’s the Perl DateTime project, which was an explicit and clearly thought out wheel reinvention exercise. The existing wheels were all kind of broken, and you couldn’t easily put any two wheels on the same car, so we came up with a plan for a whole set of interchangeable wheels and assorted other parts.

Nowadays I spend a lot of time on Moose, which is one of the most recent (and by far the best) in a long series of “make Perl 5 OO better” modules.

To top off my wheel-ish history, I have a new ORM, Fey::ORM, meaning I am the creator of both one of the oldest and one of the newest ORMs on CPAN.

Truly, I am the master of wheels, both re-invention and polishing those already in existence.

Well, I thought I was getting better, but I was wrong. Last week my infection seems to have had a resurgence, and I’m not feeling well enough to travel.

Yuval Kogman has offered to teach the Moose tutorial at OSCON, so that will still go on, assuming O’Reilly agrees to the switch.

I’m still hoping to go to Italy in October. If I’m not recovered by then, I’m just going to have to get a robot body, because this meat sack is not working out so well.

A recent thread on the Mason users list reminded me of the problems I had grokking Catalyst when I first looked at it. Raymond Wan wrote “I’m skimming over the MVC part and as my system doesn’t use an SQL database, I’m wondering if Catalyst is overkill??”

Those of us who know Catalyst know that this question is based on some wrong assumptions, but it’s easy to see why Raymond has those assumptions. Look at the Catalyst tutorial. In the very first chapter, it’s already talking about databases and DBIx::Class.

It’s easy to look at this and assume that Catalyst is somehow tightly bound to DBIx::Class or SQL databases.

The problem is that the tutorial docs really need to serve two different audiences, though both audiences are Catalyst newbies.

On the one hand, you have people with relatively little web app experience. Presumably, they know some Perl, and they do a web search for “perl web application framework”. Eventually, they’ll get to Catalyst and start reading about it. For those people, being given a set of standards and a full walk through of Model and View (in addition to Controller) is very valuable. It gives them all the tools they need to get started on simple web apps without having to make too many choices.

The other audience is people who have some real web app development experience with something more primitive than Catalyst. These could be people coming from a Mason-based site without any real controllers, or people who used something like Apache::Template with mod_perl, or maybe they wrote their own controllers “by hand” using the mod_perl API.

Many of those folks will already have some experience with models. To refer back to Raymond, presumably his system already has some sort of model code, it just doesn’t use a SQL DBMS. Those people will look at the existing Catalyst tutorial and get confused. Isn’t Catalyst flexible? Then why does it look like RoR, with all my tool choices made for me?

It took me a while to realize that Catalyst, at its core, is smaller than you might think, and you can use just the pieces you like.

The very core of Catalyst is its dispatching system. Given a URI, it selects a piece of code to run. Its dispatcher is very powerful (Chained methods are great!), and with plugins like Catalyst::Action::REST, it’s even better.

Along with the dispatching system, Catalyst also provides an abstraction over the typical web app request/response cycle. The Request makes it easy to look at incoming query arguments, POST data, file uploads, and headers. The Response lets you set headers and return output to the client, whether that be HTML or a downloadable file.

Catalyst also includes engines (think “environment adapters”) for a number of common web application environments, including vanilla CGI, mod_perl, FastCGI, and more. These engines make sure that the Request/Response API works exactly the same in any environment where Catalyst can be deployed.

This is a huge win, since you can write your app without worrying about the deployment environment. If you’re writing an app for public distribution, it gives the installing users a choice of how to deploy.

These core pieces are really the only parts of Catalyst you have to use when you use Catalyst. If you don’t want dispatch and a request/response API, you don’t want Catalyst.

Catalyst (really Catalyst-Devel) also includes a fantastic single-process development server. This server can be started straight from an application’s checkout directory with one command. Even better, this dev server can be told to monitor all relevant files and restart itself when any of them change. Note that this is a proper restart, which avoids all the myriad problems that afflict Apache::Reload and its ilk, which attempt to reload modules in the same Perl interpreter.

Just these things – controllers, a request/response abstraction, deployment agnosticism, and a great dev environment – are enough to make Catalyst a great choice. Ignore everything else it does and you’ll still have improved your development process and improved your code.

Catalyst also does some other things …

It has a component system which has allowed people to release a whole host of useful plugins. If you look on CPAN, you’ll find things like sessions, powerful authentication, dumb authentication, I18N, and much more. If a plugin does what you need, it’ll save you a lot of development time.

Note that the old “Catalyst::Plugin” system is in the process of being deprecated, but the concept of pluggable components is still core to what Catalyst is. All that’s changed is the way pluggability works.

Catalyst lets you have multiple views. While many apps will just output HTML via a templating system, this flexibility is great for RESTful apps that may want to output XML, JSON, and still fall back to HTML for browsers (see my REST-ForBrowsers for some help with that).

Catalyst also has configuration file handling built-in. Personally, I avoid it, because it only works within the context of the whole “Catalyst environment”. That means it’s awkward at best to load the configuration outside of the web environment. I always make sure that application wide setting are available for things like cron jobs. This falls into a category of Catalyst features which are not best practices, but are probably useful for people writing their first web app.

Catalyst gives you hooks for models. Again, this is something I never use, but it’s another “useful for web app n00bs” feature.

There’s probably many other things I’ve left out. The point is that Catalyst provides a very powerful set of core web app tools, and that core is actually small.

Relative to a “my way or the highway” type framework (RoR and Jifty, I’m looking at you), it’s easy to port an existing application to Catalyst. In fact, using Catalyst::Controller::WrapCGI, you can wrap an existing CGI application with Catalyst, and then convert slowly over to “native” controllers.

And most importantly, you can move to Catalyst without touching your model at all! Since many applications have the bulk of their code in the models (at least, they do if you’re doing it right), this is a huge win.

Next step is to turn some of this rambling into doc patches. I think a section of the Catalyst tutorial aimed at folks coming from an “old school” web app background would be great, and would really help people like Raymond (and would’ve helped me a few years back).