Skip to content

Latest commit

 

History

History
163 lines (124 loc) · 4.35 KB

REST.mdown

File metadata and controls

163 lines (124 loc) · 4.35 KB

Putting, Modifying and the REST

Until now, the texts had to be hard coded into the fixture. That of course is just ridiculous for a webapp. The whole point of an application like this is that it is interactive, so that I can publish my own texts, modify my old ones and delete the garbage.

As you might know, the HTTP has four main verbs:

  • GET: A content is shown, no modification should occur.
  • POST: Modify a content by sending the server information.
  • PUT: Create new content on the server by URL
  • DELETE: What do you think?

There are some others, but these four help you design your interface. For example, our application manages texts, so the following requests should be possible:

  • GET /text should display a list of all texts.
  • PUT /text should publish a new text.
  • GET /text/:id should display the text with the given id.
  • POST /text/:id should modify the text.
  • DELETE /text/:id ...What do you think?

Using only meaningful URLs and HTTP methods and not cookies, etc, to navigate the user through the site is known as REST. Not only does it give an simple interface, it also helps performance, etc. Putting a cool new name on it like "REST" on it hides the fact, that this was how the makers of HTTP imagined the web all along.

Sinatra is RESTful by default, but of course, you have to take care of the URLs yourself. The last time, we defined the two GET methods, so lets add publishing a new text first:

post "/text" do
  text = Text.new(params[:title], params[:text])
  text.save
end

Pretty easy, huh? The params will come from a form, but that's not our problem now.

Next, we can post changes:

post "/text/:id" do
	text = Text.by_id(params[:id].to_i)
  
	return 404 if text.nil?

  text.title, text.text = params[:title], params[:text]
end

This mixes the two sources for params.

delete "/text/:id" do
	text = Text.by_id(params[:id].to_i)
  
	return 404 if text.nil?
  
  text.delete
end

Ok, now we can face the problem, that we can't actually access these methods, since we don't have a form for the editing part yet.

First of all, we notice that it would be stupid to write the same form twice - once for the editing and once for the creating. We'd prefer to just show the same form. This problem can be solved with partials: basically, we insert a HAML call into the HAML template. Define a HAML file form.haml, and use it from both new.haml and edit.haml.

# form.haml

%form(action = actionurl method = "POST")
  %label
    Title:
    %input(type='text' name="title" value="#{title}")
  %label
    Text:
    %input(type='textarea' name="text" value="#{text}")
  %input(type='submit')

# edit.haml

%h1
  Edit
  %q= @text.title
= haml :form, :locals => {:title =>  @text.title, :text => @text.text, :actionurl => "/text/#{@text.id}"}

# new.haml

%h1 New Txt
= haml :form, :locals => {:title =>  "", :text => "", :actionurl => "/text"}

We need to add URLs for the form of course, for example

get "/text/new" do
	haml :new
end

get "text/:id/edit" do
	@text = Text.by_id(params[:id].to_i)

	haml :edit
end
  • Instead of adding :locals, you can also define instance variables. This is often preferable.

There is only putting the respective links into the views:

# index.haml
%ul
  - for text in texts
    %li
      %a( href="/text/#{text.id}" )= text.title
%a( href="/text/new" ) new text

# show.haml
%h1
  = text.title
%div
  :markdown
    #{text.text}
%ul
  %li
    %a(href="/text/#{text.id}") edit
  %li
    %form(action="/text/#{text.id}" method="POST")
      %input(name ="_method" type="hidden" value="delete")
      %input(type="submit" value="delete")

You might be wondering, what the heck the line

%input(name ="_method" type="hidden" value="delete")

is about. Fun fact: Browsers can't use PUT or DELETE. It's embarrassing but true. The fix is the following: We sent a POST, which tells the server that it actually should have been a DELETE method. Sinatra understands this and translates.

Please don't let GET requests change anything on the server, or a google spider might delete all your posts.

You should now know

  • What REST is and how RESTful application typically build up their URLs.
  • How to use partials.
  • How to use the PUT and DELETE methods, even though browsers don't support it.