Created
February 19, 2009 14:26
-
-
Save harrikauhanen/66941 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Gisted by harri.kauhanen ('AT') gmail.com | |
# | |
# Coucher - Super simple RESTful HTTP service with Rack and CouchFoo | |
# Should work easily with ActiveRecord or other persistence frameworks. | |
# This demo only supports HTTP GET requests on existing resources. | |
# With tiny modifications it could support JSON output or Etag caching. | |
# | |
# Feel free to use and modify, but let me know your ideas as well, thanks! | |
# | |
# | |
# To run it, you could e.g. 'rackup coucher.ru -p 3000' or attach to any Rack-capable server. | |
# Or you could easily make it a Rails Metal and run along with the Rails stuff. | |
# | |
# | |
# File: coucher.ru | |
# | |
# require 'rubygems' | |
# require 'rack' | |
# | |
# require 'coucher.rb' | |
# run Coucher.new | |
# | |
# | |
# To consume the service, you could use HTTP GET to e.g. these resources: | |
# | |
# http://localhost:3000/people/ | |
# http://localhost:3000/people/52a4e65a6735a65e899a120ef2e6a572 | |
# http://localhost:3000/people/52a4e65a6735a65e899a120ef2e6a572/dogs | |
# http://localhost:3000/people?name=Harri | |
# http://localhost:3000/dogs/1793f7d6647b72d4f00c029c1b1649b5/person | |
# | |
require 'rubygems' | |
require 'couch_foo' | |
class Person < CouchFoo::Base | |
property :name, String | |
has_many :dogs | |
end | |
class Dog < CouchFoo::Base | |
property :name, String | |
property :person_id, String | |
belongs_to :person | |
end | |
# | |
# Define more models here. Note! No need to define "routes" or anything, HTTP interface just works. | |
# | |
class Coucher | |
def initialize | |
CouchFoo::Base.set_database(:database => 'people_and_dogs', :host => "localhost:5984") | |
end | |
def call(env) | |
if env['REQUEST_METHOD'] != 'GET' | |
return fail(400, 'This demo supports only GET requests') | |
end | |
slash, classname, id, nesting, other = env['PATH_INFO'].split('/') | |
if other || classname.nil? | |
return fail(400, 'Invalid path') | |
end | |
begin | |
clazz = Kernel.const_get(classname.classify) | |
if id | |
if nesting | |
res = clazz.find(id).send(nesting) | |
if res.nil? | |
return [200, {"Content-Type" => "text/xml"}, ["<?xml version='1.0' encoding='UTF-8'?><nil />"]] | |
end | |
else | |
res = clazz.find(id) | |
end | |
else | |
conditions = CGI.parse(env['QUERY_STRING']) | |
res = clazz.all(:conditions => conditions) | |
end | |
return [200, {"Content-Type" => "text/xml"}, [res.to_xml]] | |
rescue CouchFoo::DocumentNotFound => e # or an ActiveRecord exception | |
return fail(404, 'Resource not found') | |
rescue NameError | |
return fail(400, "Class not found") | |
end | |
end | |
def fail(code, message) | |
return [code, | |
{"Content-Type" => "text/xml"}, | |
["<?xml version='1.0' encoding='UTF-8'?><error>#{message}</error>"]] | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment