Freitag, 23. Januar 2009

REST In Piece

The Very BEST Of REST (The Praxis)

Since you know the abstract of REST (otherwise read "Take A REST" first), we'll start to drive the train to REST. Fasten your seat belts!

I will use a simple sample to demonstrate the way REST works in Rails. We will talk about a person/ people to manipulate. As I mentioned in the previous article the Controller maps the resource/ object of class ActiveRecord::Base.

I assume you have a database running. I skip that part, because it depends on your preferences which DMS you use. I don't care if it's a sqlite, mysql or whatever. I use postgres.

All In One (Line)

As you already know:
~/blogspot$ rails train
creates a rails application named train. And who goes by train? Correctly, it's all about people:
~/blogspot$ script/generate scaffold person name:string surname:string age:integer
Our People have a name and a surname the same as an age. This one liner creates the model Person in the a app/models/person.rb:
class Person < ActiveRecord::Base
end
Don't forget to
~/blogspot$ rake db:migrate
to have the appropriate table in the database after you set up your config/database.yml (you know how). The extra benefit is the line
map.resources :people
in the config/routes.rb to create the routes and their URL helper. I will touch it later on once again. But that's not all. The extra extra benefit is the app/controllers/people_controller.rb (I compressed the comments a bit; you can compare with your own generated):

The Controller

class PeopleController < ApplicationController
  def index
    @people = Person.find(:all)
    respond_to do |format|
      format.html # GET /people --> index.html.erb
      format.xml{render :xml => @people} # GET /people.xml
    end
  end

  def show
    @person = Person.find(params[:id])
    respond_to do |format|
      format.html # GET /people/1 --> show.html.erb
      format.xml{render :xml => @person} # GET /people/1.xml
    end
  end

  def new
    @person = Person.new
    respond_to do |format|
      format.html # GET /people/new --> new.html.erb
      format.xml{render :xml => @person} # GET /people/new
    end
  end

  def edit
    @person = Person.find(params[:id]) # GET /people/1/edit
  end
  
  def create
    @person = Person.new(params[:person])
    respond_to do |format|
      if @person.save
        flash[:notice] = 'Person was successfully created.'
        format.html{redirect_to(@person)} # POST /people
        format.xml{render :xml => @person, :status => :created, :location => @person} # POST /people.xml
      else
        format.html{render :action => "new"} # failed validation
        format.xml  { render :xml => @person.errors, :status => :unprocessable_entity }
      end
    end
  end

  def update
    @person = Person.find(params[:id])
    respond_to do |format|
      if @person.update_attributes(params[:person])
        flash[:notice] = 'Person was successfully updated.'
        format.html{redirect_to(@person)} # PUT /people/1
        format.xml{head :ok} # PUT /people/1.xml
      else
        format.html{render :action => "edit"} # failed validation
        format.xml{render :xml => @person.errors, :status => :unprocessable_entity}
      end
    end
  end

  def destroy
    @person = Person.find(params[:id])
    @person.destroy
    respond_to do |format|
      format.html{redirect_to(people_url)} # DELETE /people/1
      format.xml{head :ok} # DELETE /people/1.xml
    end
  end
end

Gosh! Can you believe that one single script/generate does such an incredible job for you? It definitely takes more time to explain all these lines and what it means for you than typing it. Not to mention how long it would take these lines. It's unbelievable but that's not all yet...

The extra extra extra benefit are some new templates generated in app/views/people:

The Templates

  • index.html.erb
  • show.html.erb
  • edit.html.erb

These templates are for rendering the actions "index", "show" and "edit".

The template app/views/people/index.html.erb:

Listing people

<% for person in @people %> <% end %>
Name Surname Age
<%=h person.name %> <%=h person.surname %> <%=h person.age %> <%= link_to 'Show', person %> <%= link_to 'Edit', edit_person_path(person) %> <%= link_to 'Destroy', person, :confirm => 'Are you sure?', :method => :delete %>

<%= link_to 'New person', new_person_path %>

Please be patient. I will go through it in a moment.

The template app/views/people/show.html.erb:

Name: <%=h @person.name %>

Surname: <%=h @person.surname %>

Age: <%=h @person.age %>

<%= link_to 'Edit', edit_person_path(@person) %> | <%= link_to 'Back', people_path %>
The template app/views/people/edit.html.erb:

Editing person

<% form_for(@person) do |f| %> <%= f.error_messages %>

<%= f.label :name %>
<%= f.text_field :name %>

<%= f.label :surname %>
<%= f.text_field :surname %>

<%= f.label :age %>
<%= f.text_field :age %>

<%= f.submit "Update" %>

<% end %> <%= link_to 'Show', @person %> | <%= link_to 'Back', people_path %>
And at least the new.html.erb:

New person

<% form_for(@person) do |f| %> <%= f.error_messages %>

<%= f.label :name %>
<%= f.text_field :name %>

<%= f.label :surname %>
<%= f.text_field :surname %>

<%= f.label :age %>
<%= f.text_field :age %>

<%= f.submit "Create" %>

<% end %> <%= link_to 'Back', people_path %>

... man, the Rails train is an incredible fast thingie (The Concorde wouldn't be faster, if it still flew). And it does all for you, including RESTful routes. This standardized controller and its templates handle the CRUD of every person in the train.

Right now the more tedious job to explain about what's going on is waiting for the poor author (me).

REST URLs vs. Granny URLs

Let's start with the created PeopleController. It contains the seven actions to process the people of the resource class Person (model). The list below abstracts them in short manner.
Action HTTP Route helper URL Response
index GET people_path /people Collection of all people
show GET person_path(@person.id) /people/1 Person with id 1 (to show)
new GET new_person_path /people/new New Person with nil attributes for creation
edit GET edit_person_path(@person.id) /people/1/edit Person with id 1 for update
create POST people_path /people Person with new created id and attributes (sent by form)
update PUT person_path(@person.id) /people/1 Person with updated attributes (sent by form)
destroy DELETE person_path(@person.id) /people/1 Collection of all people except the person with id
The route helpers are generated by the routes.rb dynamically. You can ask for them by
~/blogspot$ rake routes
Comparing the RESTful routes and the old fashioned way:
Action RESTful URL old fashioned URL
index /people /people/index
show /people/1 /people/show/1
new /people/new /people/new
edit /people/1/edit /people/edit/1
create /people /people/create
update /people/1 /people/update/1
destroy /people/1 /people/destroy/1

Do you see the differences? I mean, do you realize the sweetness of the REST URLs? The URL doesn't declare anything about the action. They are stripped to their resource they represent. Who knows what to do with the resource (URL) "/people/1"? Show, update or destroy it? Nobody knows. The HTTP verb declares it. And that's how it should be. No resource-action mixup anymore, anytime!

The Special Requests

Testing the application creates logs according to the requests.

Show request:

Processing PeopleController#show (for 127.0.0.1 at 2009-01-26 19:40:52) [GET]
Parameters: {"action"=>"show", "id"=>"1", "controller"=>"people"}
Update request:
Processing PeopleController#update (for 127.0.0.1 at 2009-01-26 19:41:01) [PUT]
Parameters: {"commit"=>"Update", "person"=>{"name"=>"Destra", "surname"=>"Garcia", "age"=>"29"},
"authenticity_token"=>"87b9c2baa4e1114ca0b97384253ac6c283f19cee", "_method"=>"put", 
action"=>"update", "id"=>"1", "controller"=>"people"}

Please survey the parameters hash sent by the form. First it contains the data of person called Destra Garcia (btw. the best female soca artist ever). But more interesting is the "_method"=>"put", which is responsible for pointing to update action instead of show (remember the equal URL). Who caused it? I will mention it, when I go into detail of the edit.html.erb template. For now it's sufficent to just know it.

Destroy request:
Processing PeopleController#destroy (for 127.0.0.1 at 2009-01-26 20:07:57) [DELETE]
Parameters: {"authenticity_token"=>"87b9c2baa4e1114ca0b97384253ac6c283f19cee",
"_method"=>"delete", "action"=>"destroy", "id"=>"1", "controller"=>"people"}

Once again the "_method" parameter with its value "destroy" this time. The "authenticity_token" helps to prevent XSRF server side and is part of all create, update and destroy requests.

Now let's take a deeper look into the sent headers with the help of curl (nice tool to send/ receive data to/ from a server using amongst others HTTP).
~/blogspot$ curl -H "Accept: text/html" -i -X GET http://localhost:3000/people/1
It returns the header and the HTML response (I omitted the uninteresting stuff):
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
So the show action responded to the HTML request. It also does when requesting XML:
~/blogspot$ curl -H "Accept: application/xml" -i -X GET http://localhost:3000/people/1
The response:
HTTP/1.1 200 OK
Content-Type: application/xml; charset=utf-8

succeed with the requested resource in a XML styleee. You also can test it in your browser with URL localhost:3000/people/1.xml (assumed that you run your server on port 3000 and there is a resource people/1). Why does the server can respond to different requests using the same action? Sugar, sugar, Rails. Yep! Rails evaluates the header and returns the appropriate resource in the requested mode. HTML? XML (Webservice via ActiveResource gives a broad hint)? No problem. You will use the same action and you're done. Lucky guy.

It's time to render the response, isn't it? By default rails searches for the HTML template to render (when there is no respond_to call). Since 2.0 we use ERB for rendering HTML. The files are marked with the extension html.erb; remember the automatically generated templates when I used scaffold to generate the person resource.

The Links In Detail

Now let's elaborate to the index.html.erb, just to pick up the first one.

It renders the collection of people. Basically it contains a table with the people our table can deliver. As by former scaffolding, there are also the three links to work the single entity. Show, Edit and Delete, just to name it. "Show" shows the entity in detail. The URL is generated by assigning the object itself. Rails inspects the object and assumes the controller by its class (a controller represents a resource!). This way to generate the URL is a polymorphic one. But that doesn't matter at this point. I just wanted to mention it, because I explain it in a later article ;) . The URL "/people/1" will call the show action of PeopleController. You also could have used the explicit version "person_path(person)" instead of just assigning simply the object. The next link for calling the edit action named "Edit" is an example of an explicit URL helper: edit_person_path(person). It's one of the dynamically generated helper. Rails simply extracts the id of the passed object. So the call also could look like edit_people_path(person.id). You better save your energy for typing the longer version and watch the last link ("Destroy") in the line. As you already know, the HTTP verb "delete" needs to be sent to call the destroy action. The browser is unable to do it, so let Rails do the job. I set the :method option of the link_to helper to :delete. So Rails realizes that it has to generate a form. For obvious reasons it is not a HTML form. Right now it's sufficient to know that the link establish a form on click:

Destroy

Before sending the form you will have to confirm, if you really are sure to destroy the item. If so, the form will be sent with the already mentioned attributes, "_method" => "delete" amongst others. Please compare the href attribute of the "Destroy" link with the "Show" href.

The "New person" link is described briefly. It uses the explicit helper new_person_path to generate "/people/new".

The show.html.erb template contains two links. One to "Edit" the chosen item and another one ("Back") to return to the complete collection. I already declared the "Edit" link before. And to return to the people is pretty easy. The URL helper people_path does it.

O.K. the next template (edit.html.erb) is more interesting, I swear. I suppose I don't need to describe the both links "Show" and "Back" once again. So I start with form. It is generated by the form_for helper. And by the way I advise you to make extensive use of it. It's a sweet one, believe me. It expects an object and instantiates a form object of it, you conveniently can use to access the attributes to fill the form input and select fields as I describe in another article. The HTML of the form looks like:

// ...

You're right. The URL is equal to the one calling the show action ("Show"). And it does POST as every form should. But it also sends a parameter called "_method" with the value "put", affiliated by a hidden field. And that reveals the request to be PUT (update action). The same trick used for calling the destroy action

The form of the new.html.erb doesn't need any trick. It just uses the form's POST to be POST:

Here you also can admire the fancy form_for helper. I really appreciate it.

Oh lord, to write these lines took a lot more time than creating the life cycle of the person resource itself. I hope you enjoyed it. So do yourself a favour and take a REST and relax.

Nice up your App!

Take A REST (The Theory)

Since Rails 1.2 there was a chat about REST and what it means for us (at the end of the food chain). Before giving some practical examples on how to use it in Rails in a later paper I'd like to write some notes about its theory.

Once upon a time ...

No. Seriously. In 2000 Roy Fielding launched REST in a dissertation. REST stands for Representational State Transfer, which naming includes all about what's going behind the curtain. I try to define each single word in a short briefing in hope that nobody will hurt me for its oversimplification:
  • Representational stands for: Every resource is represented by an own unique URI (so it is a mapping URI == resource/data/HTML/object/PDF/whatever_you_want_it_to_be)
  • State means to have some HTTP verbs, which job is to declare what to do with this resource (I will describe these verbs later)
  • Transfer is self-explanatory (isn't it?)

Please let me emphasize the Representation thingie once again: an URI represents a RESOURCE. It's not that I like wagging forefingers, it's because of the later understanding why Rails generates such routes.

O.K. now I will name these HTTP "verbs" (as I promised; and I always keep my promises ;) ) In the orignal HTTP specification there a declared the following request methods:
  1. GET: get a resource
  2. POST: update a resource
  3. PUT: create a resource
  4. DELETE: delete a resource
  5. HEAD: returns metadata of a resource
  6. TRACE: returns the original query the server received (e.g to compare, if the query was fiddled intermediately)
  7. OPTIONS: returns a list of features the server supports
  8. CONNECT: for ssl tunnel

The first two should be known very well. That is why I don't go into detail how a get or post request looks like. Apart from that Wiki does.

But reading the list carefully you certainly noticed that the leading four verbs map the CRUD (Create/ Read/ Update/ Delete) actions needed to proceed the full life circle an object is going through (maybe you knew before, but if so why the hell are you still reading this article?). Anyway, the Rails guys catched these four verbs to implement REST in RoR ('R' words are great!). So they had to reactivate PUT and DELETE, though we all know that the common browser don't know them (in situations like this I always remember the words of Bill Gates a browser was just a little snippet of code...)

... sorry for drifting away. The Rails community solved it by sending (posting) the verbs as parameters as I describe in the article "The very BEST of REST". A short answer as long as IE & Co. keep on being dumbly. To put it in a nutshell, a RESTful Rails application uses HTTP verbs "GET", "POST", "PUT" and "DELETE" to get, create, update and delete resources (objects) represented by the URI.

Believe it or not, that's all REST is about.

Now let's come to terms.

The pros:
  • Clean URLs representing only the resource itself without any actions
  • Different Responses of the same action are possible depending on the request (HTML, Ajax, XML).
  • Less code through prevention of code repetitions (DRY) by using the same action for different requests (Multiclient).
  • CRUD based Controller represent a specific kind of resource (simplifies and cleans up the structure of controllers).
  • Clean Controllers are easier and enjoying to maintain
The contras:
  • You have to get familiar with a new technique

Sounds like an easy decision to make. So make it and pimp your Rails application with REST.

I still didn't characterize how? True dat, mon!

Read The very BEST of REST!!

Mittwoch, 21. Januar 2009

How To Blog Ruby

My wish to blog about some Ruby'n'Rails stuff is coming true and Boom! there was the first issue. How to hightlight the syntax of the ruby code snippets? Gosh! But fortunately there is the SyntaxHighlighter :) based on CSS and JavaScript. Now i describe how I got it working.

I promise you, it's done in 3 steps.

Step 1

Download the SyntaxHighlighter (just follow the link above) and you should receive a lot of files.

The shCore.js and SyntaxHighlighter.css are essentially. The first one makes the code looking as the second file wants it to look like: Bling Bling.

The rest of JS pack are shBrushXXX.js files amongst others the shBrushRuby.js. Now you have to park them somewhere in the world wild web. I abused Geocities for it but Google's Sites should do the job the same. It doesn't matter. The main point is that they are available. Otherwise no Bling Bling.

To be able to highlight more kind of code like SQL, CSS, JScript or XML I uploaded the appropriate shBrushSql.js, shBrushCss.js, shBrushJScript.js and shBrushXml.js too.

Step 2

Before getting the code snippets sparkling you better should include the needed files inside the head tags as I did:

<link type="text/css" rel="stylesheet" href="http://your_server/path/to/SyntaxHighlighter.css">
<script src="http://your_server/path/to/shBrushRuby.js" language="javascript"></script>
<script src="http://your_server/path/to/shBrushSql.js" language="javascript"></script>
<script src="http://your_server/path/to/shBrushCss.js" language="javascript"></script>
<script src="http://your_server/path/to/shBrushJScript.js" language="javascript"></script>
<script src="http://your_server/path/to/shBrushXml.js" language="javascript"></script>
and before the closing body tag :
<script language='javascript'>
dp.SyntaxHighlighter.ClipboardSwf = 'http://your_server/path/to/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');
</script>
Don't miss it. It's a must have.

Did you notice something? Yeah man, it's the first piece of code glitter. Calm down, the next bit is coming. Let's make the blog talk ruby in ... ...

Step 3

O.K. ruby is the first choice of talking and so we start our very first ruby snippet rrrrright now. Man, how exciting! And it's that easy.

Use the <pre> tag for wrapping the code and set the name attribute to code and the class attribute to whatever you want to look like, for example:

<pre name="code" class="ruby">
  class Person < ActiveRecord::Base
    def talk
      "Bla bla bla"
    end
  end
<pre>
which looks on your blog in real:
  class Person < ActiveRecord::Base
    def talk
      "Bla bla bla"
    end
  end
Oh gosh! How sweet! And the story goes on...

You can set some options as mentioned at the SyntaxHighlighterWiki. At the end let me give you these advises:

  • Escape your HTML characters "<" and ">" by "&lt;" and "&gt;" inside the snippets
  • Switch off the line breaks of your blog, otherwise you will see tons of "</br>"

So hurry up to make your own RockinRails blog look pretty!

KaBoom!!!