(Looking for DHH’s keynote at RailsConf Europe 2007? Find it here)
I’d been looking forward to David Heinemeier Hanssons (DDH) key note in the same way I’m guessing people looks forward to hearing Bill Gates and Steve Jobs talking at the big Microsoft and Apple conferences. Any community needs its mythical founder amongst whom the community can revolve, and DHH makes a good job of filling that role, backed up by wise men such as the Fowlers and the Pragmatics.
DHH had just returned from a trip to a Ruby conference in Japan, and - still very much jetlagged, as he explained later that evening in the bar - introduced the topic of his key note: CRUD. Create, Read, Update, Delete. An idiom so widespread that they even teach it in my Java-centric school, an abbreviation that lays out the four basic operations of manipulating database tables. DHH explained that he has lately started seeing all his code in the light of CRUD, in fact, he starts to spot “crudness” everywhere – perhaps CRUD can be used as the basic pattern for making beautiful code?
DHH pointed out the similarities between CRUD, database operations, Rails actions and – last but not least – the http methods:
- Read,
SELECT,findandGET - Create,
INSERT,createandPOST - Update,
UPDATE,updateandPUT - Delete,
DELETE,destroyandDELETE
When you browse to a url like GET /people/show/1, you are basically repeating yourself: show is redundant, because the http method sent by the browser has already specified that you want to do a GET. So the beautiful version of the url would be GET /people/1, just as PUT /people/1 is more beautiful than POST /people/update/1.
The problem is, however, that even though the http protocol specifies all of the mentioned methods, only GET and POST has achieved wide spread use, and thus, specifying PUT or DELETE as the method on a form tag won’t work as intended, since browsers just ignores it and defaults to GET, and if even if it is capable of passing the method on, many web servers and proxies sees the use of methods like PUT and DELETE as unsafe and rejects them. No problem, DHH said, we’ll just fake it in Rails using a hidden field to specify PUT and DELETE methods. This should raise some alarm bells, he continued, and it certainly did with me. By using a hidden field I get ugly flashbacks (well, wish they were flashbacks, I’m still doing loads of .NET) to the heavy use of hidden fields in .NET which result in 500 KB pages - excluding images – so asked, at the Rails Core Q&A session, if this wasn’t a slippery slope taking Rails in a wrong direction?
No, DHH answered without hesitating, we’ve done plenty of things that could be a slippery slope before. It’s a hack, and we might be able to take it away eventually, but right now it’s the way to go. I guess I’ll just have to try it out, since the Simply Restful plugin, which promotes this kind of urls, will be implemented in Rails 1.2, according to the Rails Core team (and they should know it).
Tightly connected to the point about restful urls, is DHH’s newly found desire to promote controllers that only do the four CRUD operations. Basically, he argues, if you have more than the default actions in a controller; index, show, list, new, create, edit, update and delete, you haven’t thought enough how to structure your controllers and actions. If have “scoped” actions like add_user or post_comment, you haven’t “crudified” your application, and you should move those actions to a UserController or a PostController.
As I discussed later with Victoria, many of the brilliant people at RailsConf are self taught college drop outs doing cool projects their own way, instead of worrying about learning the “right way” at school. But with this “crudness” or “crudiness” DHH wants the controllers to respect, I actually think he is trying to phrase a concept both of us learned about, while getting our bachelor’s degree in Business Administration and Computer Science at the Copenhagen Business School: Normal form. Normal form is known concept throughout logic, language and mathematics theory, but from my education, I know it from database theory. It’s all about optimizing your database by normalizing your tables into a certain normal form, and I’d guess that’s what DHH wants us to do: To normalize our controllers.
I realize DHH is not too interested in databases – during the Rails core team Q&A he said in fact: “I don’t like databases. I pretty much use them as hashes.” – but I like the analogy, and I propose we start talking about normalization in this context, because really, normalization is just another word for beauty. However, beauty is a bit unspecific and it’s widely used to describe anything good in Rails, so why not instead say: I’ve normalized my controllers and action to the CRUD normal form. There are in fact things we can learn from traditional school paradigms such as relational algebra or object oriented design, or maybe it’s just general programming wisdom which has some how snuck into education, and one of those things is this: “If you think about it a bit harder, a simpler approach will appear.” (DHH). You do this when you normalize databases. You do this when draw UML diagrams. And now you should do it when you normalize controllers – think simpler, think CRUD!
But: CRUD is not a goal in itself, it’s an aspiration, a design technique, DHH emphasized, and normalizing (“crudding”) won’t be the answer to everything. Basically though, you can normalize anything, and DHH gave examples with the state of case having its own model and its own controller – this way, the CaseController was normalized, and didn’t have to had any add_state actions or something like that – instead, these actions was implemented in the StateController through the standard CRUD actions. At first, DHH explained at the Rails Core Q&A, he thought login was an example of actions that couldn’t be normalized, but Jamis Buck had the solution for this, implementing CRUD actions on a SessionController, since that’s basically what a login does; adding and removing stuff in the session.
Enough with the theory. The big revelation of the key note was a new API DHH started hacking away at two days before the key note; Active Resource. The API is basically all about describing things as resources, and as I understand it after discussing it with Geoffry Grosenbach and Chris McGrath, it’s basically an alternative to Action Webservice based on the REST concept. Since it’s still work in progress, I’m not really sure it’s going to work at all, but it seems like it will usable for both providing an API as well as consuming it. I guess DHH don’t want to repeat the work on the Basecamp API now that he is doing Sunrise, but also, he wants to emphasize that almost anything can be viewed as a resource. Active Resource will be released as a small, compact plugin as part of Rails 1.2.0, and basically, it sounds like that release will very much focus on the REST principles, and on making the Rails core smaller by pulling thing out in plugins.
The example DHH gave on using Active Resource was based on his notion on viewing XML basically as a hash. So perhaps your code would look like this:
Person = ActiveResource::Struct.new do |p| p.uri “http://www.example.com/people” p.credentials :name => “dhh”, :password => “secret” end matz = Person.find(1)
- and Active Resource will automatically wrap the XML response, which could look like this:
<person> <name>Matz</name> </person>
For now, we’ll just have to wait and see what turns up in Edge Rails and try it out.
Jaikus
I admit that even with a fancy Comp Sci degree I was pretty hazy on what normal form meant in relation to databases. Now that I looked it up on Wikipedia I agree that this is exactly right, and for the same reasons:
“Instead of attempting to lump all information into one table, data is spread out logically into many tables”
Obviously a Good Thing for well documented OO reasons. What I didn’t realize is how much database theorists like it - for data integrity and efficiency, not just clean URLs and easy web services.
Comment by Jim Greer — June 25, 2006 @ 9:24 pm
Minor clarification: ActiveResource is definitely not about providing services, just consuming them.
Comment by Scott Raymond — June 26, 2006 @ 12:59 pm
[…] Frequency and format of future meetings. I’ve already had great discussions about the format about this with Olle and Jakob. This thursday we’ll keep it as an informal meetup with focus on getting to know each other and discuss whatever is on top of people’s mind. For future meetups I suggest we meet after work - probably not on a cafe but maybe at somebodys office. Also I expect we have one or more topics, and I also expect that one or more participants prepare talks. First candidate could be to learn more about the recent RailsConf, that Casper Fabricius has been blogging (Casper wrote he couldn’t join us this thursday because of Roskilde, but I’m sure he’ll join us next time). […]
Pingback by justaddwater.dk | Thoughts regarding Ruby on Rails Meetup this week — June 26, 2006 @ 2:31 pm
Hey Casper, thanks for posting this detailed information from RailsConf, and for all the great pictures you posted on del.icio.us! I was pretty blown away by DHH’s presentation, I am glad to see that rails is becoming more concise as an API as it becomes more rich.
Comment by Jeremy Seitz — June 26, 2006 @ 2:34 pm
[…] Casper Fabricius also has a nice article where he takes a closer look at the next big thing in Rails (1.2) which is the use of REST. […]
Pingback by RailsConf at REST — June 28, 2006 @ 1:40 am
Check your links… the ones to “REST”, “Normal Form” and “http protocol” are messed up.
Comment by Tony — June 28, 2006 @ 9:29 am
First thank for this excelent review of DHH key note, REST is a really interesting “technology” and it is interesting the way it will be integrated into Rails. Second, and Off Topic: Please register you blog at RubyCorner.com (and remenber to configure the ping ;-) it is a meeting place for people interested in the Ruby Programming Language or any of the related technologies.
Comment by Aníbal Rojas — June 28, 2006 @ 4:55 pm
dysfunksional.monkey said 3 days later:
Regarding the REST methods, are you sure that POST is create and PUT is update? After reading the spec (http://www.faqs.org/rfcs/rfc2616) I came to the conclusion that its the other way round, in that PUT creates a resource (returning 201 on create or 200 on replace) whereas POST handles updates (things such as “Annotation of existing resources”) returning 200 on success or, if the update also creates a resource, a 201 header which should “contain an entity which describes the status of the request and refers to the new resource, and a Location header”. Am I wrong?
Comment by dysfunksional.monkey — June 29, 2006 @ 11:48 am
Sorry, copied/pasted my comment from here: http://jimonwebgames.com/articles/2006/06/26/dont-say-crud-say-fucd - hence the “dysfunksional.monkey said 3 days later:”.
Comment by dysfunksional.monkey — June 29, 2006 @ 11:49 am
[…] I said I was interested in talking a bit about Rails’ new direction wrt HTTP verbs: it seems Casper Fabricius and the web has most of the information at hand: so enjoy Casper’s introduction to the new concepts. […]
Pingback by Olle Jonsson’s Morningstar » HTTP verbs and Rails — June 30, 2006 @ 1:19 am
dysfunksional.monkey
I haven’t really studied the spec that much in detail, I’m just repeating what DHH said at the key note. Maybe he got it wrong - you should probably take that up with him.
Aníbal Rojas
Thanks. I’ve registered my blog and set up the ping
Tony
Guess I shouldn’t do spell in Word, seems to mess up my links. Thanks, they should be fixed now.
Comment by Casper Fabricius — July 1, 2006 @ 5:13 am
Thanks Casper. Just a little worried as I’ve seen these comments in more than one place at the moment, and if I’ve interpreted it correctly then it looks as though the Rails camp is getting things wrong, which could be costly in the future.
Comment by dysfunksional.monkey — July 4, 2006 @ 7:03 am
Well, browsers don’t support ’s method to be anything else from “get” or “post” because HTML 4.01 says so by the way: http://www.w3.org/TR/html4/interact/forms.html#submit-format
This is, however, different for XForms where “put” is allowed but “delete” is not. Logically, deletion of resource is identified purerly by request-uri and as that should be specified in nchor element which is now by specs not possible.
Comment by Kamil Kukura — July 8, 2006 @ 10:00 pm
[…] RailsConf: Create, Read, Update, Delete: Normalize […]
Pingback by Refactoring a Rails app to be RESTful — July 21, 2006 @ 4:34 am
[…] RailsConf was a blast. But I barely had the time to consume all the impressions, since my vacation was just after the event in Chicago. So I went directly to Roskilde Festival, North Europes biggest festival with 100.000 partying people near Copenhagen, Denmark, and from there I got on a bus to Rumania as part of choir singing Danish songs in the Rumanian churches. When I got back, I realized my blog had gained quite a lot of attention (at least compared to it’s very silent past), not at least my posts on David Heinemeier Hansson’s and Paul Graham’s key notes. While 70 subscribers and 200 visitors a day doesn’t sound like much to some, it fills me with a certain amount of humility: “Surely people will expect my future to be of high professional quality and deep insight”, I think. […]
Pingback by Fingerprints of Casper Fabricius » RailsConf: People I met — July 22, 2006 @ 4:06 pm