A suggestion: I looked through the README and the book, and I couldn't
find an example of how to access the body of a POST or PUT without
treating it as HTML FORM params. I had to dig through the Rack API
docs, and I think that 'request.body.read' is what's needed.
Anyway, here's a sample REST application, using JSON for the fun of
it, which you're welcome to include if you wish (or fix if it's
broken :-)
--- myapp.rb ---
require 'rubygems'
require 'sinatra'
require 'json'
require 'widget'
get '/widgets.json' do
Widget.all.to_json
end
get '/widgets/:id.json' do
Widget.find(Integer(params[:id])).to_json
end
post '/widgets.json' do
item = JSON.parse(request.body.read)
raise "Bad object" unless item.is_a? Widget
Widget.add(item).to_s # see note below
end
--- widget.rb ---
# Rubbish model, not thread-safe!
class Widget
attr_accessor :id, :name, :price
def initialize(id, name, price)
@id, @name, @price = id, name, price
end
def to_json(*a)
{
'json_class' =>
self.class.name,
'data' => [ @id, @name, @price ],
}.to_json(*a)
end
def self.json_create(o)
new *o['data']
end
def self.all
@all ||= []
end
def self.add(item)
@seq ||= 0
@seq += 1
item.id = @seq
all << item
return @seq
end
def self.create(*args)
add(new(*args))
end
def self.find(id)
all.find { |item|
item.id == id }
end
end
Widget.create(nil, "flurble", 12.3)
Widget.create(nil, "boing", 4.56)
Note: I'm not exactly sure what a REST API should return in response
to a successful POST. Here I've just returned the new Widget's ID. But
notice that I had to do .to_s to make this work. If I return an
integer from the Sinatra post method, I just get an empty body back
(Content-Length: 0)