Articles
resource_controller plugin
For those of you learning or using Ruby on Rails, here are my notes on Fabio Akita’s excellent screencast tutorial for James Golick’s resource_controller plugin. I find it to be useful to be able to refer to a written document quickly instead of having to watch the entire hour presentation if you forget something. Feel free to report errors or inaccuracies in my notes. I hope you find the notes to be handy too.
Notes on Fabio Akita’s screencast: http://www.akitaonrails.com/2008/1/25/easy-restful-rails-screencast
Topic: James Golick’s resource_controller plugin for Ruby on Rails: http://jamesgolick.com/resource_controller
Problem #1: RESTful controllers almost always have 7 methods that look nearly the same. There is a lot of repetitive code. This is not DRY. Instead, wouldn’t it be great if you could inherit from a standard RESTful superclass and just configure your controller if it needed.
Problem #2: When you have a has_many relationship between two models, and want to nest your routes. e.g. http://yoursite.com/posts/42/comments/3, then you have to change all your links in all your sub-model’s views. This is kind of a pain.
Solution: resource_controller plugin provides that RESTful superclass and generators to replace all the repetitive code and makes your controllers skinny like models. Standard models are customizeable through a DSL-like API provided by the plugin. Generic helper functions for views are also provided so that helper links are generic so you don’t have the problem of customizing links when making nested routes (is this true?).
This tutorial describes how to create blog of postings with a Post model and a Comment model.
The Comment model is polymorphic which means that it can be used to place comments not just on the Post model but any other model in the application.
Also, the Comment model will be using nested routes.
How to install:
In your rails_root application directory type:svn export http://svn.jamesgolick.com/resource_controller/tags/stable vendor/plugins/resource_controller
How to use the generator
ruby script/generate scaffold_resource Post title:string body:text
How to create a polymorphic has_many submodel
ruby script/generate scaffold_resource Comment commentary:references comment:text
Note: you need to make your own css and application layouts:
public/stylesheets/scaffold.css app/views/layouts/application.html.erb
CONTROLLERS
Now your controllers are skinny:
# /app/controllers/posts_controller.rb
class PostsController < ResourceController::Base
end
/app/controllers/comments_controller.rb
class CommentsController < ResourceController::Base
end
ResourceController::Base inherits from the usual ApplicationController
MODELS
Now modify your Post model to express the has_many relationship with the Comment model.
Ie. A post have many comments.
# /app/models/post.rb
class Post < ActiveRecord::Base
has_many :comments, :as => :commentary
end
Note: For non-polymorphic relationships you don’t need :as => commentary.
Modify your Comment model to have the polymorphic belongs_to relationship.
# /app/models/comment.rb
class Comment < ActiveRecord::Base
belongs_to :commentary, :polymorphic => true
end
How polymorphic tables works: Your comments table has two columns (in addition to the text field that stores your comment): commentary_id and commentary_type. commentary_type is the name of the table you want to reference. commentary_id is the row in the table that you’re referencing. In this way you can associate a comment to any row in any table in your database. You can comment on anything in your application.
CREATING A POST HAS_MANY COMMENT RELATIONSHIP, WHERE COMMENT IS POLYMORPHIC.
MIGRATIONS You need to modify your 002_create_comments.rb migration to make it polymorphic.
# /db/migrate/002_create_comments.rb
class CreateComments < ActiveRecord::Migration
def self.up
create_table :comments, :force => true do |t|
t.references :commentary, polymorphic => true
t.text :comment
t.timestamps
end # do
end # def self.up
def self.down
drop_table :comments
end
end # class
Now run your migration.
rake db:migrate
Now you need to add “belongs_to :post” to your controller.
This will make it so that you don’t have to load the parent resource in your controller like this
@post = Post.find(param[:post_id])
“belongs_to :post” will automatically load your parent resource. This reduces a lot of repetitive coding.
# /app/controllers/comments_controller.rb
class CommentsController < ResourceController::Base
belongs_to :post
end
Modify your routes.rb file to enable nested routing.
# /config/routes.rb file
ActionController::Routing::Routes.draw do |map|
map.resources :posts, :has_many => :comments
end
VIEWS In your /app/views/comments/_form.html.erb file, take out the commentary field, cuz that’s not something that is user-facing. It’s an internal field used to implement polymorphism.
Start up your server
script/server
Go to
http://localhost:3000/posts/new
Create dummy data in your database by filling out the form.
Now, you should be able to add a comment to that posting. (Assum your posting has an id of 1.) Go tohttp://localhost:3000/posts/1/comments/new
Fill out the form. It should have created a new comment linked to your post record with id 1.
Check to see if the comment has been associated with your post using the console: script/console
>> Post.find(1)
=> #<Post id: 1, title: "My first post", body: "restful post", .......>
>> Post.find(1).comments
=> [#<Comment id: 1, commentary_id: 1, commentary_type: "Post", comment: "This is a new comment." ......>]
>> Comment.count
=> 1
Where is the magic happening? Let’s look at the edit comment view.
Normally, without using the resource_controller plug, with nested resources, you would have to refer to the parent resource as post_comment_url(@post, @comment). With resource_controller, all you have to do is use: “object_url”. Ie. in the old way, the helper method names are coupled to the names of your models. In the new way, the information of the relationships are taken from the controller, and helper method names are independent of the names of the models. (Coupling is generally bad, because it means your code is brittle and linked dependent on other parts of your code. Independence is good because it makes your code more modular.)
# /app/views/comments/edit.html.erb
....
<%= link_to 'Show', object_url %> |
<%= link_to 'Back', collection_url %>
ADDING ANOTHER COMMENTABLE MODEL CALLED “ARTICLE”
To see the value of a polymorphism, let’s create another model called Article and use the same comments table to store comments on articles. Use the resource_controller generator to create articles:
ruby script/generate scaffold_resource Article title:string
author:string article:text
Create the database table.
rake db:migrate
Configure the models
Add the has_many clause.
# /app/models/article.rb
class Article <ActiveRecord::Base
has_many :comments, :as => :commentary
end
Configure the routes.rb file
# /config/routes.rb
ActionController::Routing::Routes.draw do |map|
map.resources :articles, :has_many => :comments
map.resources :comments
map.resources :posts, :has_many => :comments
end
Finally, add :article to the belongs_to method call in CommentsController
# /app/controllers/comments_controller.rb
class CommentsController < ResourceController::Base
belongs_to :post, :article
end
Now it should work.
Let’s say you already input an article with id of 1.
Then add a comment to your article
http://localhost/articles/1/comments/new
CREATING AN ADMIN NAMESPACE
Let’s say you want only the admin to create, edit, or delete Post instances.
Make an admin folder in in /app/controllers and /app/views.
mkdir app/controllers/admin
mkdir app/views/admin
mkdir app/views/admin/posts
Copy your your Post views into /app/views/admin/posts
Note the all the post views still exist in the normal directory location at this point. They are still accessible publicly at this point.
cp app/views/posts/* app/views/admin/posts/
Copy your post controlelr into /app/controllers/admin
Note: there are going to be 2 copies of the controller, one for the public and one for the admin. See how we configure each later.
cp app/controllers/posts_controller.rb app/controllers/admin
Modify your posts controller. Just add “Admin::” to the front of your PostsController.
# /app/controllers/admin/posts_controller.rb
class Admin::PostsController < ResourceController::Base
end
To restrict editing ability of posts from the public, delete the following files _form, edit, and new.html.erb in /app/views/posts/.
rm app/views/posts/_form.html.erb
rm app/views/posts/new.html.erb
rm app/views/posts/edit.html.erb
Take out the links to edit functionality in your remaining views:
app/views/posts/index.html.erb
remove these lines:
<%= link_to 'Edit', object_url(post) %>
<%= link_to 'Destroy', object_url(post), :confirm => ......... %>
<%= link_to 'New Post', new_object_url %>
Remove similar links in the show page: app/views/posts/show.html.erb
Configure the public PostsController:
# /app/controllers/posts_controller.rb
class PostsController < ResourceController::Base
actions :all, :except => [:new, :edit, :create, :update, :destroy]
end
Create the namespace routes in routes.rb. Add the following link at the bottom of your routes list in routes.rb
# /config/routes.rb
ActionController::Routing::Routes.draw do |map|
...
map.namespace :admin do |admin|
admin.resources :posts
end
end
If necessary restart your web server.
Now you can access:
http://localhost:3000/admin/posts
Note: Your admin section will have access to new, edit, destroy, etc..
And your public access is here:
http://localhost:3000/posts
NOW LET’S ADD PAGINATION BY CUSTOMIZING THE WAY THE POST CONTROLLER BUILDS COLLECTIONS OF POSTINGS. A COLLECTION IS A VARIABLE USED WHEN YOU WANT TO DISPLAY A LIST OF ALL YOUR RECORDS.
First, install the will_paginate plugin. By the way, there is a free screencast on will_paginate here: http://railscasts.com/episodes/51 Here is the command to install the plugin:
script/plugin install svn://errtheblog.com/svn/plugins/will_paginate
Without customization the PostsController builds collections like this: @collection = Post.find(:all) We want to customize this. Define the collection method to overwrite the way collections are built. end_of_association_chain is the way resource_controller plugin refers to the name of the model in question. In this case it will return the Post controller. If we were in the CommentsController, it would return the Comment model associated with params[:post_id].
private
def collection
@collection ||= end_of_association_chain.paginate :page => params[:page], :per_page => 5
end
Note: The paginate function comes from the will_paginate controller.
# /app/views/posts/index.html.erb # Add pagination links at the bottom.
....
<%= will_paginate @posts %>
OTHER METHODS FROM RESOURCE_CONTROLLER
For more documentation and helper methods, take a look at the resource_controller README file:
/vendor/plugins/resource_controller/README
For example,
To customize the create method. Place this inside your controller:
create do
# Sample customization code and methods:
flash "Object was created successfully! Right on!"
wants.js {render :template => "show.rjs"}
failure.wants.js {render :template => "display_errors.rjs"}
end
To create a before filter before your controller’s new method, place this in your controller:
new_action.before do
3.times { object.tasks.build } # This is just an example of a customization.
end
To customize the way your controller builds an individual object for the view, overwrite the build_object method.
private
def build_object
@object ||= end_of_association_chain.build_my_object_some_funky_way object_params
end
If that was your PostsController, then in your posts views you would be able to access your @post variable like normal, but it would be built in the funky way as prescribed by the way you defined build_my_object_some_funky_way method.
See the README for many other functions.
Posted by David Beckwith on Mar 24, 2008
git, an alternative to SVN
These are my notes from watching the git peepcode video. I highly recommend peepcode.com videos. I feel slightly guilty for publishing his notes for his screencast, which costs $9, but I hope this page will ultimately sell more of his screencasts.
“git” is source control software. For those of you who are not programmers, source control software is software that tracks changes in your files for several reasons:
- When collaborating on a set of files with a team of people, source control software will prevent you from overwriting somebody else’s changes to a file. You must explicitly resolve the conflicts before merging your changes into the repository.
- It creates a time machine of your code and allows you to literally view the state of all your files in a project at any point in time in the past. This is helpful if you unwittingly introduced a bug into your code and want to rollback to a state where the bug wasn’t there.
- It can be used to track different branches of development, representing different purposes or levels of stability.
Using source control software is considered to be a best-practice in software engineering. The current standard open source tool is called SVN or Subversion. Subversion is very good, and we use it in the office daily. git offers a few improvements on subversion, namely
- response-time / performance (very easy to work locally to make commits fast)
- agility (easy to make branches and makes you a faster programmer)
- distributed, so you can synchronize with your laptop, desktop, friend’s computer, or work computer without having to always connect to a centralized server.
You can do all of these things with SVN, but git just makes it a lot easier to. You can think of git as the “sqlite3” of version control software (source control). Not a huge deal, but if it saves me a few minutes each day, then it’s worth switching to it.
website: git.or.cz
Features of git:
- offline: All files are committed with respect to a local repository. Therefore, git can always be used offline. No need for central server or internet.
- distributed: can share git repository with peers—not just server.
- agile branching: branching becomes easier than in SVN: makes you more agile
- emphasizes content not files…. not sure how this helps me though.
INSTALLATION Mac: sudo port install git-core
Others: install from source and compile.
Latest: git clone git://git.kernel.org/pub/scm/git/git.git
CONFIGURE identify yourself to git: email and your name git config—global user.name “David Beckwith” git config—global user.email “dbitsolutions@gmail.com”
To view all users: git config—list OR cat .gitconfig
SET UP ALIASES git config—global alias.co checkout
VIEW YOUR CONFIGURATION cat .gitconfig
TO IGNORE WHITESPACE (Ruby is whitespace insensitive) git config—global apply.whitespace nowarn
Some nice aliases: gb = git branch gba = git branch -a gc = git commit -v gd = git diff | mate gl = git pull gp = git push gst = git status
START USING GIT: git init
TO IGNORE SOME FILES MAKE A FILE (in the root directory) CALLED .gitignore and add some files to it: # comments begin with hash. *.log db/schema.rb db/schema.sql
TO SCHEDULE THE ADDITION OF ALL FILES TO THE NEXT COMMIT: git add .
TO SEE WHAT THE STATUS: git status
TO COMMIT: git commit -m “First import”
TO SEE WHAT HAS BEEN COMMITTED: git ls-files
TO SCHEDULE DELETION OF A FILE:
git rm
TO COMMIT ALL CHANGES IN FILES IN THE CURRENT REPOSITORY: git commit -a
TO SCHEDULE THE ADDITION OF AN INDIVIDUAL FILE TO THE NEXT COMMIT:
git add
TO VIEW THE DIFFERENCE AS YOU COMMIT USE THE -v OPTION git commit -v
TO COMMIT AND TYPE THE MESSAGE ON THE COMMAND LINE USE THE -m OPTION git commit -m “This is the message describing the commit”
TO COMMIT AND GET AUTOMATICALLY ANY CHANGES FROM OTHER PEOPLE USE THE -a OPTION git commit -a
THE NORMAL COMMIT COMMAND: git commit -a -v
TO VIEW A LOG OF YOUR COMMITS git log
TO VIEW A LOG OF YOUR COMMITS WITH A GRAPH TO SHOW THE EXTENT OF THE CHANGES git log—stat
TO HAVE PAGINATION WHEN VIEWING THE LOG FILE USE THE -v OPTION git log -v
TO VISUALIZE YOUR CHANGES gitk—all
TO CREATE A NEW BRANCH:
git branch
TO VIEW ALL OF THE EXISTING BRANCHES git branch
TO VIEW A LIST OF ALL BRANCHES git branch -a
TO SWITCH TO ANOTHER BRANCH. The state of your file system will change after executing this command.
git checkout
TO MAKE SURE THAT YOUR NEW BRANCH GETS CHANGES FROM THE MASTER BRANCH (WHERE EVERYBODY ELSE IS WORKING) USE THE REBASE COMMAND: git rebase master
TO MERGE YOUR NEW BRANCH INTO THE MASTER BRANCH.- first switch back to the master branch. git co master
- check to see what changes you’re about to merge together, compare the two branches: git diff master xyz
- if you’re in the xyz branch, and want to merge the xyz branch into it. git merge xyz
TO REVERT YOUR CHANGES to before the merge. git reset—hard ORIG_HEAD
TO RESOLVE CONFLICTS just edit your file. Remove the markings, add the file, then commit.
TO CREATE A BRANCH AND SWITCH TO THE BRANCH IN ONE MOVE:
git checkout -b
TO CREATE A “CLIPBOARD” or “STASH” OF CHANGES THAT ARE NOT YET COMMITED (SO THAT YOU CAN SWITCH TO ANOTHER BRANCH IN THE MIDDLE OF YOUR CHANGES.), CREATE A STASH. git stash “Put a message here to remind you of what you’re saving to the clipboard”
TO SWITCH AWAY FROM THE CURRENT BRANCH git co- do whatever
- switch back to the stashed branch
git co
TO VIEW THE LIST OF STASHES git stash list
TO LOAD BACK THE “CLIPBOARD” OR “STASH” git stash apply- now you can continue to work where you were previously.
TO DELETE A BRANCH THAT IS NOT USED ANYMORE, but already merged into the current branch. (TO CLEAN UP)
git branch -d
TO DELETE AN UNMERGED BRANCH
git branch -D
TO DELETE THE STASH. (ERASE THE “CLIPBOARD” FROM MEMORY) git stash clear
TO SET UP YOUR REPOSITORY FOR SHARING ON A CENTRAL SERVER- Copy up your repository. e.g.: scp -r my_project deploy@yourbox.com:my_project
- Move your files on the remote server to /var/git/my_project
- For security make the owner of this project git
- On the repository server: sudo chown -R git:git my_project
- then (for security) restrict the “deploy” user to doing git-related things in /etc/passwd with a git-shell.
TO CHECK OUT THE GIT REPOSITORY TO YOUR LOCALHOST. ON YOUR LOCAL HOST do this: git clone git@yourbox.com:/var/git/my_project
TO SEE SOME INFO ABOUT THE REPOSITORY THAT WILL TELL YOU WHICH REPOSITORY IS THE MASTER AND WHICH IS THE SLAVE: cat .git/config
- By virtue of having cloned the remote repository, your local repository becomes the slave and will track and synchronize with the remote master branch.
TO UPDATE YOUR LOCAL BRANCH FROM THE REMOTE SERVER: git pull
TO GET A COPY OF THE ENTIRE REMOTE REPOSITORY (e.g. a repository named “laptop”) WITHOUT MERGING THEM INTO YOUR LOCAL BRANCHES USE FETCH git fetch laptop
TO MERGE TWO LOCAL BRANCHES (ie. your local xyz branch with your local master branch) USE MERGE git merge laptop/xyz- this merged the (already copied laptop repository’s xyz branch) with the current branch you’re sitting in.
TO MERGE THE REMOTE BRANCH WITH YOUR LOCAL BRANCH THAT YOU ARE SITTING IN USE PULL
TO ADD LOCAL KNOWLEDGE (TO YOUR LOCAL REPOSITORY) OF A 2ND REMOTE REPOSITORY, LIKE YOUR LAPTOP git remote add laptop duo2book.local:repos/m_project- “laptop” is the name of the remote repository. “duo2book.local” is the name of the machine, I guess
TO VIEW META INFORMATION ABOUT THAT REMOTE REPOSITORY git remote show laptop
TOP PUSH A COMMITTED LOCAL CHANGE OF THE xyz BRANCH TO THE REMOTE laptop BRANCH git push laptop xyz
TO CREATE A TRACKING BRANCH (A SLAVE BRANCH). Ie. to link a local branch to a remote branch:
git branch—track
NOW IF YOU’RE SITTING IN THE LOCAL TRACKING BRANCH, TO PULL YOU DON’T NEED TO SPECIFY THE REMOTE TRACKING BRANCH: git pull
- Note: you can tracking different branches from different remote machines. For example, you can track your friend’s “upgrade” branch and track the “master” branch from your main webserver.
- By convention, ‘origin’ is the ‘centralized server’ which is the way SVN is usually set up on a remote server.
TO SEE WHICH LOCAL BRANCHES ARE TRACKING A REMOTE BRANCH: git remote show origin
TO WORK WITH AN SVN REPOSITORY BUT WORK WITH GIT LOCALLY:
git-svn clone
- Now you can work with the checked out directory as though it was a git repository. (cuz it is)
TO PUSH (COMMIT) CHANGES TO THE REMOTE SERVER git-svn dcommit
TO UPDATE YOUR LOCAL REPOSITORY FROM THE SVN REPOSITORY git-svn rebase
- NOTE: make sure you have your perl bindings to your local svn installation.
Posted by David Beckwith on Mar 21, 2008
In Praise of the Unpowerful
The title of today’s sermon: “In Praise of the Unpowerful”
I’m always amazed at how long it takes and how error-prone the process of creating a data-driven website is when the database schema is so conceptually simple, the business rules are simple, you can come up with a database-model in an hour and a complete site map and access rules in another hour, but then to actually create it, debug it, test it, etc. etc.. it takes months for really smart people to execute it to completion. What is up with that? Why is it so much more difficult than making a sign at, say, FastSigns? I can understand if it takes a day or two, but months . . . . ?
We love giving up power, but we’re in denial of that fact. Look how many constraints RoR imposes upon the structure of Ruby programs when you make a website, and how people in the Rails community get so excited they start drooling all over themselves about that. Look at REST, and how they’re loving those additional constraints as well. Look how we gave up more power, by making the default database SQLite instead of MySQL in Rails 2.0. HTML, the king of the unpowerful, is a huge huge success. (Think how many pages of HTML have been written or generated.)
I’m not sure what the best interface is going to be to manipulate directly model abstractions like UML – whether we’re using graphical IDEs or writing DSL scripts to generate code – but I just like the idea of language creation as a general problem solving approach. . . . I have a feeling this direction hasn’t been explored enough. . . . . especially of course in the direction of less powerful languages. I’m thinking that there should some really easy way to create DSLs in general. Like we need software that supports the creation of DSLs. . . . .Maybe that’s Ruby, but maybe it’s more than that.
Lately, I’ve been kind of intrigued by the notion of the Principle of Least Power in programming languages.
I think our tools are simply WAY TOO POWERFUL for our own good. Even Rails is way too fine-grained for most peoples’ good. Yes, I understand that people need to write Othello games in Javascript sometimes and connect to funky-ass payment gateways with their custom APIs. But there is a huge class of websites that are doing the same shizzle over and over again.
I like the idea of thinking about languages in terms of subsets of power. Give the least powerful subsets to the dumbest people with the least experience to do the easiest tasks, and the most powerful supersets to the smartest people with the most experience to execute the hardest tasks – but don’t make the learning curve humungous for the dumb people – cuz that defeats the purpose. (I don’t mean that they’re stupid actually, they’re just lacking knowledge and experience like me. Just a rhetorical device . . . . to illustrate a point.) For example, PHP is way too powerful for most professional programmers with 2-3 years of experience. Have you ever seen maintainable PHP code? I have once, and it was autogenerated. Same goes for Rails. . . . . It’s way too easy even with the directory structure they made for you to write unmaintainable code. TOO MUCH FREEDOM.
Rails is my current favorite framework, and I still enjoy it a lot. But, there should be a really dumb easy way to make a website that requires no knowledge, no configuration, no fancy complicated command lines. It should just be one line of code or one line of code that takes an input file for the schema, and an input file for the permissions. . . . okay and one more for the interface (I know that sounds like MVC, but I’m thining of something much higher level than Ruby or Erb). I shouldn’t have to be configuring observers and turning on and off switches, configuring mongrel clusters, looking at log files, and debugging my deploy.rb file. Making a simple RoR programming is like sitting in the cockpit of a 747 with 5,000,000 switches staring at you in the face.
On the other hand, I like scaffold generators in Rails. They are essentially creating a high-level declarative language with a command line interface and I think that’s great, but still it’s way too complicated. I should not have to read several thousand page textbooks to deal with the aftermath of having typed that command. Hmm . . . . . maybe I just need to get more involved with Rails code generators.
Sorry, I didn’t mean to rant. . . . . it’s 3 a.m. here . . . . . :)
Posted by David Beckwith on Feb 03, 2008
Why CRUD and REST is important
For a long time, I didn’t get what the big deal is about pretty URLs like
http://www.example.com/people/1
I still don’t completely get it, but Roy Fielding, who is one of the authors of the original HTTP specification, defined REST in his PhD thesis at the University of Irvine in 2000. Roy Fielding’s dissertation
David Heinemeier Hansson, the creator of Ruby on Rails, says he didn’t get it either for a long time until he actually started using it. His talk at RailsConf 2006 explains why pretty URLs are not just pretty URLs. After listing to his talk, I started to want to learn more about the REST architectural style.
1. CRUD (create read update delete) is a design philosophy. If you find that your application code is getting complicated, you’re probably not done modeling. Your controllers, for the most part, should only have 7 actions: index, new, create, show, edit, update, and destroy. Don’t just model the nouns as classes. When you start modeling the relationships between the nouns like “subscriptions” and “memberships,” DHH claims that your controllers will start looking like CRUD, and your code will no longer be handling exotic exceptional cases and complicated business rules. If your controllers don’t look like CRUD, it means that you’re not done: you haven’t finished thinking about your model deeply enough. DHH reminds us not to forget to model (make classes for) things like relations, events, and states.
2. One of the beneficial side-effects when using ActiveResource (the Rails library supporting CRUD) is that you can use one controller for many clients and get web services, RJS, and mobile phone formats with little or no extra programming.
3. Another good side-effect is discoverability. If everybody followed this convention it would be very easy, if not automatic, to discover web services and APIs simply by knowing the name of the thing that you’re looking for. People can start using your web service to make more interesting applications that combine different web services. It’s kind of like how a UNIX script calls many stateless little programs and strings them together to do something really cool.
David Heinemeier Hansson’s talk
Download the Power Point slides as a PDF file here.
For me, the bottom-line is less code by following conventions. But, I think the point of REST is much more than that. By following this convention and accepting the constraints that REST puts on the way you create and design your applications, not only do you write less code, but you get emergent properties induced by these constraints.
(Slide 23 of Roy Fielding’s RailsConf Europe talk)
I think some of these emergent properties include, 1. layeredness and serendipity (people can create cool stuff from your data if you expose it to them), 2. simplicity (1 URI per model exposed as XML …. that’s pretty simple.), 3. scalability, 4. cacheability, 5. discoverability, 6. reliability.
Fielding’s dissertation takes a couple of cups of coffee to finish, so here are some nice REST tutorials for the rest of us.
There’s a lot to be said about REST, so it’s best you check out the original thesis and some of the many tutorials referenced here. Good luck on your path to coming to peace with REST. As for me, I’m going to start writing RESTful rails apps and see where it takes me. . . . .
Posted by David Beckwith on Oct 28, 2007