Skip to content

Commit

Permalink
Add support for RESTful API, works now with create,read nodes/propert…
Browse files Browse the repository at this point in the history
…ies (#26 state:open)
  • Loading branch information
andreasronge committed Apr 2, 2009
1 parent 87e56b2 commit 405ec34
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/rest.rb
@@ -0,0 +1 @@
require 'rest/rest'
58 changes: 58 additions & 0 deletions lib/rest/rest.rb
@@ -0,0 +1,58 @@
# This is a complete example and a spike of how RESTful Neo4j API would work

require 'rubygems'
require 'json'
require 'sinatra/base'
require 'neo4j'

# This mixin creates the following restful resources
# POST /[classname]/ Response: 201 with Location header to URI of the new resource representing created node
# GET /[classname]/[neo_id] Response: 200 with JSON representation of the node
# GET /[classname]/[neo_id]/[property_name] Response: 200 with JSON representation of the property of the node
# PUT /[classname]/[neo_id]/[property_name] sets the property with the content in the put request
#
# TODO delete and RESTful transaction (which will map to neo4j transactions)
#
module RestMixin

def self.included(c)
classname = c.to_s

Sinatra::Application.get("/#{classname}/:id/:prop") do
content_type :json
node = Neo4j.load(params[:id])
{params[:prop]=>node.get_property(params[:prop])}.to_json
end

Sinatra::Application.put("/#{classname}/:id/:prop") do
content_type :json
node = Neo4j.load(params[:id])
property = params[:prop]
body = request.body.read
data = JSON.parse(body)
value = data[property]
return 409, "Can't set property #{property} with JSON data '#{body}'" if value.nil?
node.set_property(property, value)
200
end

Sinatra::Application.get("/#{classname}/:id") do
content_type :json
node = Neo4j.load(params[:id])
return 404, "Can't find node with id #{params[:id]}" if node.nil?
node.props.to_json
end

Sinatra::Application.post("/#{classname}") do
p = c.new
data = JSON.parse(request.body.read)
p.update(data)
redirect "/#{classname}/#{p.neo_node_id.to_s}", 201 # created
end
end
end


#
#
#Sinatra::Application.run! :port => 9123
102 changes: 102 additions & 0 deletions test/rest/rest_spec.rb
@@ -0,0 +1,102 @@
$LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/../../lib")
$LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/..")

require 'neo4j'
require 'spec'

require 'spec/interop/test'
require 'sinatra/test'

Sinatra::Application.set :environment, :test

class Person
include Neo4j::NodeMixin
# by includeing the following mixin we will expose this node as a RESTful resource
include RestMixin
property :name
end

describe 'Restful' do
include Sinatra::Test

before(:all) do
Neo4j.stop
FileUtils.rm_rf Neo4j::Config[:storage_path] # NEO_STORAGE
FileUtils.rm_rf Lucene::Config[:storage_path] unless Lucene::Config[:storage_path].nil?
end

it "should create a new Person on POST /Person" do
data = { :name => 'kalle'}

# when
post '/Person', data.to_json

# then
status.should == 201
response.location.should == "/Person/1"
end

it "should be possible to follow the location HTTP header when creating a new Person" do
data = { :name => 'kalle'}

# when
post '/Person', data.to_json
follow!

# then
status.should == 200
body = JSON.parse(response.body)
body['name'].should == 'kalle'
end

it "should find a Person on GET /Person/neo_node_id" do
# given
p = Person.new
p.name = 'sune'

# when
get "/Person/#{p.neo_node_id}"

# then
status.should == 200
data = JSON.parse(response.body)
data.should include("name")
data['name'].should == 'sune'
end

it "should return a 404 if it can't find the node" do
get "/Person/742421"

# then
status.should == 404
end

it "should be possible to get a property on GET /Person/[node_id]/[property_name]" do
# given
p = Person.new
p.name = 'sune123'

# when
get "/Person/#{p.neo_node_id}/name"

# then
status.should == 200
data = JSON.parse(response.body)
data['name'].should == 'sune123'
end

it "should be possible to set a property on PUT /Person/[node_id]/[property_name]" do
# given
p = Person.new
p.name = 'sune123'

# when
data = { :name => 'new-name'}
put "/Person/#{p.neo_node_id}/name", data.to_json

# then
status.should == 200
p.name.should == 'new-name'
end

end

0 comments on commit 405ec34

Please sign in to comment.