Obviously I want to do it with my current preferred language Ruby.
Reading different articles about major differences between Rails and Sinatra micro-framework I have decided to build the simple REST web service I need using Sinatra.
I am here sharing what I have done. This is something I put together quite quickly, so it is not complete.
Anyone of you which wants to help can contribute.
Let's install the necessary ruby gems.
# cd ~ # # mkdir rails_api # # mkdir rails_api/json # # sudo gem install sinatra # # sudo gem install rabl # # sudo gem install oj # # sudo gem install data_mapper # # sudo gem install dm-sqlite-adapter # # sudo gem install thin
I am using Rabl gem as this provides great flexibility in creating JSON replies to API request
Now in the rails_api/json directory create 3 files with the below content
#post.rabl object @post attributes :id, :title, :body #posts.rabl collection @posts attributes :id, :title, :body #error.rabl object @error attributes :messageThose files render the JSON replay to our RESTful API call. Now in the rails_api directory create the following file
#rest_api.rb
require 'rubygems'
require 'sinatra'
require 'rabl'
require 'data_mapper'
require 'json'
######## setup sqlite DB ########
DataMapper.setup(:default, 'sqlite:rest_api.db')
######## Post Model ########
class Post
include DataMapper::Resource
property :id, Serial # An auto-increment integer key
property :title, String # A varchar type string, for short strings
property :body, Text # A text block, for longer string data.
end
DataMapper.finalize
Post.auto_upgrade!
######## Very simple Error class ########
class Error
attr_accessor :message
def initialize(mex)
@message = mex
end
end
######## register Rabl. This is required for Sinatra ########
Rabl.register!
######## retrun 404 in case of invalid URL request ########
not_found do
status 404 #page not found
end
######## simple helper to return HTTP 400 ########
def status_400(mex)
@error = Error.new(mex)
status 400
rabl :'error', :format => "json", :views => 'json'
end
######## simple helper to return HTTP 404 ########
def status_404(mex)
@error = Error.new(mex)
status 404
rabl :'error', :format => "json", :views => 'json'
end
######## simple helper to return HTTP 200 ########
def status_200
status 200
end
######## simple helper to return HTTP 201 ########
def status_201(link)
status 201
#headers "location:/post/43"
headers "Location" => link
end
######## REST CRUD APIs for Post resource ########
######## index of Post ########
#GET post
get '/post' do
@posts = Post.all
if @posts.empty?
status_404("The reuqested resource does not exists")
else
status_200
rabl :'posts', :format => "json", :views => 'json'
end
end
######## show one Post ########
# GET /post/:id
get '/post/:id' do
@post = Post.get(params[:id])
if @post.nil?
status_404("The reuqested resource does not exists")
else
status_200
rabl :'post', :format => "json", :views => 'json'
end
end
######## create a Post ########
#POST /post
post '/post' do
begin
post_data = JSON.parse request.body.read
if post_data.nil? or !post_data.has_key?('title') or !post_data.has_key?('body')
raise "exception"
else
post = Post.create(:title => post_data['title'], :body => post_data['body'])
post.save
status_201("/post/#{post.id}")
end
rescue => ex
status_400("Invalid client request")
end
end
######## Update a Post ########
#PUT /post/:id
put '/post/:id' do
begin
put_data = JSON.parse request.body.read
if put_data.nil? or !put_data.has_key?('title') or !put_data.has_key?('body')
raise "exception"
else
post = Post.get(params[:id])
if post.nil?
status_404("The reuqested resource does not exists")
else
post.title = put_data['title']
post.body = put_data['body']
post.save
status_200
end
end
rescue => ex
status_400("Invalid client request")
end
end
######## Remove a Post ########
#DELETE /post/:id
delete '/post/:id' do
post = Post.get(params[:id])
if post.nil?
status_404("The reuqested resource does not exists")
else
post.destroy
status_200
end
end
Ok now just run it with
# ruby rest_api.rb -o 0.0.0.0You should get something like this
== Sinatra/1.4.5 has taken the stage on 4567 for development with backup from Thin Thin web server (v1.6.2 codename Doc Brown) Maximum connections set to 1024 Listening on 0.0.0.0:4567, CTRL+C to stop
Let's now test our RESTful Web Service. You can use your preferred tool like POSTMAN in Chrome.
I will use the always available curl to test the typical CRUD functions
CREATE
# curl -H "Content-type: application/json" -X POST -d '{"title": "post1", "body": "this is post 1"}' http://127.0.0.1:4567/post
READ# curl http://127.0.0.1:4567/post # curl http://127.0.0.1:4567/post/1UPDATE
# curl -H "Content-type: application/json" -X PUT -d '{"title": "post 5", "body": "this is post #5"}' http://127.0.0.1:4567/post/1
DELETE# curl -X DELETE http://127.0.0.1:4567/post/1
I am sure it is quite easy to argue that the HTTP return code I have used are not correct. Looks like this is quite an open topic.
In my example here I have mapped HTTP Status Code to REST call according to what described in this article (Using HTTP Status Codes correctly in your REST Web API)
As always let me know about any improvement, suggestion or correction.
Hope this helps someone out there.
I love your blog just because of the great knowledge it has. Publish some more blogs on it, to notify others also. We also offer Ruby on Rails Web Application Services in Jaipur in which you can customize your website as per your need.
RispondiEliminaI've been looking for info on this topic for a while. I'm happy this one is so great. Keep up the excellent work تحويل الى pdf
RispondiElimina