Skip to content

Instantly share code, notes, and snippets.

@mynameisrufus
Last active August 29, 2015 14:04
Show Gist options
  • Save mynameisrufus/b6b147561fc5fa351f91 to your computer and use it in GitHub Desktop.
Save mynameisrufus/b6b147561fc5fa351f91 to your computer and use it in GitHub Desktop.
Optimistic locking in Grape
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__)))
require 'grape'
require 'my_api'
use Rack::ConditionalGet
use Rack::ETag
run MyAPI
source 'http://rubygems.org'
gem 'grape'
require 'optimistic_locking'
class MyAPI < Grape::API
helpers OptimisticLocking
resource "widgets" do
params do
requires :id
end
route_param :id do
params do
requires :name
end
put do
widget = Widget.find(params[:id])
optimistic_lock!(widget.to_json)
widget.update(name: params[:name])
widget.to_json
end
end
end
end
require 'digest'
# When a GET request is returned +Rack::ETaag+ will return the +ETag+
# header to the client, the client then needs to return the etag in the
# +If-None-Match+ header to modify the resource.
module OptimisticLocking
def optimistic_lock!(body)
digest = Digest::MD5.new
digest << body
if request.env["HTTP_IF_NONE_MATCH"] != %("#{digest}")
error!('Object is stale, If-None-Match header does not match object digest.', 409)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment