Module: Sinatra::RestAPI
- Defined in:
- lib/sinatra/restapi.rb
Overview
## RestAPI [module] A plugin for providing rest API to models. Great for Backbone.js.
To use this, simply ‘register` it to your Sinatra Application. You can then use `rest_create` and `rest_resource` to create your routes.
require 'sinatra/restapi'
class App < Sinatra::Base
register Sinatra::RestAPI
end
### RestAPI example Here’s a simple example of how to use Backbone models with RestAPI. Also see the [example application] included in the gem.
[ex]: github.com/rstacruz/sinatra-backbone/tree/master/examples/restapi
#### Model setup Let’s say you have a ‘Book` model in your application. Let’s use [Sequel] for this example, but feel free to use any other ORM that is ActiveModel-compatible.
You will need to define ‘to_hash` in your model.
db = Sequel.connect(...)
db.create_table :books do
primary_key :id
String :title
String :author
end
class Book < Sequel::Model
# ...
def to_hash
{ :title => title, :author => author, :id => id }
end
end
[sq]: sequel.rubyforge.org
#### Sinatra To provide some routes for Backbone models, use ‘rest_resource` and `rest_create`:
require 'sinatra/restapi'
class App < Sinatra::Base
register Sinatra::RestAPI
rest_create '/book' do
Book.new
end
rest_resource '/book/:id' do |id|
Book.find(:id => id)
end
end
#### JavaScript In your JavaScript files, let’s make a corresponding model.
Book = Backbone.Model.extend({
urlRoot: '/book'
});
Now you may create a new book through your JavaScript:
book = new Book;
book.set({ title: "Darkly Dreaming Dexter", author: "Jeff Lindsay" });
book.save();
// In Ruby, equivalent to:
// book = Book.new
// book.title = "Darkly Dreaming Dexter"
// book.author = "Jeff Lindsay"
// book.save
Or you may retrieve new items. Note that in this example, since we defined ‘urlRoot()` but not `url()`, the model URL with default to `/[urlRoot]/`.
book = new Book({ id: 1 });
book.fetch();
// In Ruby, equivalent to:
// Book.find(:id => 1)
Deletes will work just like how you would expect it:
book.destroy();
Defined Under Namespace
Modules: Helpers
Class Method Summary collapse
Instance Method Summary collapse
-
#rest_create(path, options = {}, &blk) ⇒ Object
### rest_create(path, &block) [method] Creates a create route on the given ‘path`.
-
#rest_delete(path, options = {}, &blk) ⇒ Object
### rest_delete(path, &block) [method] This is the same as ‘rest_resource`, but only handles DELETE (edit) requests.
-
#rest_edit(path, options = {}, &blk) ⇒ Object
### rest_edit(path, &block) [method] This is the same as ‘rest_resource`, but only handles PUT/POST (edit) requests.
-
#rest_get(path, options = {}, &blk) ⇒ Object
### rest_get(path, &block) [method] This is the same as ‘rest_resource`, but only handles GET requests.
-
#rest_resource(path, options = {}, &blk) ⇒ Object
### rest_resource(path, &block) [method] Creates a get, edit and delete route on the given ‘path`.
Class Method Details
.registered(app) ⇒ Object
96 97 98 |
# File 'lib/sinatra/restapi.rb', line 96 def self.registered(app) app.helpers Helpers end |
Instance Method Details
#rest_create(path, options = {}, &blk) ⇒ Object
### rest_create(path, &block) [method] Creates a create route on the given ‘path`.
This creates a ‘POST` route in /documents that accepts JSON data. This route will return the created object as JSON.
When getting a request, it does the following:
* A new object is created by *yielding* the block you give. (Let's
call it `object`.)
* For each of the attributes, it uses the `attrib_name=` method in
your record. For instance, for an attrib like `title`, it wil lbe
calling `object.title = "hello"`.
* if `object.valid?` returns false, it returns an error 400.
* `object.save` will then be called.
* `object`'s contents will then be returned to the client as JSON.
See the example.
class App < Sinatra::Base
rest_create "/documents" do
Document.new
end
end
129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/sinatra/restapi.rb', line 129 def rest_create(path, ={}, &blk) # Create post path do @object = yield rest_params.each { |k, v| @object.send :"#{k}=", v } return 400, @object.errors.to_json unless @object.valid? @object.save rest_respond @object.to_hash end end |
#rest_delete(path, options = {}, &blk) ⇒ Object
### rest_delete(path, &block) [method] This is the same as ‘rest_resource`, but only handles DELETE (edit) requests. This uses `Model#destroy` on your model.
212 213 214 215 216 217 218 |
# File 'lib/sinatra/restapi.rb', line 212 def rest_delete(path, ={}, &blk) delete path do |*args| @object = yield(*args) or pass @object.destroy rest_respond :result => :success end end |
#rest_edit(path, options = {}, &blk) ⇒ Object
### rest_edit(path, &block) [method] This is the same as ‘rest_resource`, but only handles PUT/POST (edit) requests.
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/sinatra/restapi.rb', line 192 def rest_edit(path, ={}, &blk) callback = Proc.new { |*args| @object = yield(*args) or pass rest_params.each { |k, v| @object.send :"#{k}=", v unless k == 'id' } return 400, @object.errors.to_json unless @object.valid? @object.save rest_respond @object } # Make it work with `Backbone.emulateHTTP` on. put path, &callback post path, &callback end |
#rest_get(path, options = {}, &blk) ⇒ Object
### rest_get(path, &block) [method] This is the same as ‘rest_resource`, but only handles GET requests.
181 182 183 184 185 186 |
# File 'lib/sinatra/restapi.rb', line 181 def rest_get(path, ={}, &blk) get path do |*args| @object = yield(*args) or pass rest_respond @object end end |
#rest_resource(path, options = {}, &blk) ⇒ Object
### rest_resource(path, &block) [method] Creates a get, edit and delete route on the given ‘path`.
The block given will be yielded to do a record lookup. If the block returns ‘nil`, RestAPI will return a 404.
In the example, it creates routes for ‘/document/:id` to accept HTTP GET (for object retrieval), PUT (for editing), and DELETE (for destroying).
Your model needs to implement the following methods:
* `save` (called on edit)
* `destroy` (called on delete)
* `<attrib_name_here>=` (called for each of the attributes on edit)
If you only want to create routes for only one or two of the actions, you may individually use:
* `rest_get`
* `rest_edit`
* `rest_delete`
All the methods above take the same arguments as ‘rest_resource`.
class App < Sinatra::Base
rest_resource "/document/:id" do |id|
Document.find(:id => id)
end
end
172 173 174 175 176 |
# File 'lib/sinatra/restapi.rb', line 172 def rest_resource(path, ={}, &blk) rest_get path, , &blk rest_edit path, , &blk rest_delete path, , &blk end |