Skip to content

Instantly share code, notes, and snippets.

@jamiehodge
Created April 11, 2012 09:07
Show Gist options
  • Select an option

  • Save jamiehodge/2358132 to your computer and use it in GitHub Desktop.

Select an option

Save jamiehodge/2358132 to your computer and use it in GitHub Desktop.
application/collection+json
require 'sinatra'
require 'rack/cache'
require 'sequel'
require 'sqlite3'
require 'yajl'
DB = Sequel.sqlite
DB.instance_eval do
create_table :tasks do
primary_key :id
String :description
FalseClass :completed, default: false
DateTime :created_at
DateTime :required_at
Integer :lock_version
end
end
class Task < Sequel::Model
plugin :optimistic_locking
plugin :timestamps, update: nil
plugin :boolean_readers
alias :dateDue :required_at
alias :dateDue= :required_at=
def_dataset_method(:date_range) do |start,stop|
filter required_at: start..stop
end
end
Task.create description: 'This is my first task', required_at: '2011-12-31'
Task.create description: 'This is my second task', required_at: '2011-12-29'
Task.create description: 'This is my third task', required_at: '2011-11-30'
use Rack::Cache
before do
content_type 'application/collection+json'
end
get '/' do
yajl :collection, locals: { items: Task.order(:required_at) }
end
post '/' do
@task = Task.new.set_only Yajl::Parser.parse(request.body.read), [:description, :completed, :dateDue]
@task.save
redirect to '/'
end
get '/;queries' do
yajl :queries
end
get '/;template' do
yajl :template
end
get '/;all' do
yajl :collection, locals: { items: Task }
end
get '/;open' do
yajl :collection, locals: { items: Task.filter(completed: false) }
end
get '/;closed' do
yajl :collection, locals: { items: Task.filter(completed: true) }
end
get '/;date-range' do
yajl :collection, locals: { items: Task.date_range(params[:'date-start'], params[:'date-stop']) }
end
before %r{^/(?<id>\d+)} do
@task = Task[params[:id]] || not_found
etag @task.lock_version
end
get %r{^/\d+} do
yajl :item, locals: { item: @task }
end
put %r{^/\d+} do
@task.update_only Yajl::Parser.parse(request.body.read), [:description, :completed, :dateDue]
redirect to '/'
end
delete %r{^/\d+} do
@task.destroy
204
end
error Sequel::ValidationFailed, Sequel::HookFailed do
redirect back
end
__END__
@@item
json = {
collection: {
href: url('/'),
version: '1.0',
links: [
{ rel: 'author', href: 'mailto:mamund@yahoo.com', prompt: 'Author' },
{ rel: 'profile', href: 'http://amundsen.com/media-types/collection/profiles/tasks/', prompt: 'Profile' },
{ rel: 'queries', href: url('/;queries'), prompt: 'Queries' },
{ rel: 'template', href: url('/;template'), prompt: 'Template' }
],
items:
[
{
href: url("/#{item.id}"),
data: [
{ name: 'description', value: item.description, prompt: 'Description' },
{ name: 'completed', value: item.completed?, prompt: 'Completed' },
{ name: 'dateDue', value: item.dateDue, prompt: 'Date Due' }
]
}
]
}
}
@@collection
json = {
collection: {
href: url('/'),
version: '1.0',
links: [
{ rel: 'author', href: 'mailto:mamund@yahoo.com', prompt: 'Author' },
{ rel: 'profile', href: 'http://amundsen.com/media-types/collection/profiles/tasks/', prompt: 'Profile' }
],
queries: [
{ rel: 'all', href: url("/;all"), prompt: 'All tasks' },
{ rel: 'open', href: url("/;open"), prompt: 'Open tasks' },
{ rel: 'closed', href: url("/;closed"), prompt: 'Closed tasks' },
{ rel: 'data-range', href: url("/;date-range"), prompt: 'Date Range',
data: [
{ name: 'date-start', value: '', prompt: 'Start Date' },
{ name: 'date-stop', value: '', prompt: 'Stop Date' }
]
}
],
template: {
data: [
{ name: 'description', value: '', prompt: 'Description' },
{ name: 'dateDue', value: '', prompt: 'Date Due (yyyy-mm-dd)' },
{ name: 'completed', value: '', prompt: 'Completed (true/false)?' }
]
},
items:
items.map do |item|
{
href: url("/#{item.id}"),
data: [
{ name: 'description', value: item.description, prompt: 'Description' },
{ name: 'completed', value: item.completed?, prompt: 'Completed' },
{ name: 'dateDue', value: item.dateDue, prompt: 'Date Due' }
]
}
end
}
}
@@queries
json = {
collection: {
href: url('/'),
version: '1.0',
links: [
{ rel: 'author', href: 'mailto:mamund@yahoo.com', prompt: 'Author' },
{ rel: 'profile', href: 'http://amundsen.com/media-types/collection/profiles/tasks/', prompt: 'Profile' }
],
queries: [
{ rel: 'all', href: url("/;all"), prompt: 'All tasks' },
{ rel: 'open', href: url("/;open"), prompt: 'Open tasks' },
{ rel: 'closed', href: url("/;closed"), prompt: 'Closed tasks' },
{ rel: 'data-range', href: url("/;date-range"), prompt: 'Date Range',
data: [
{ name: 'date-start', value: '', prompt: 'Start Date' },
{ name: 'date-stop', value: '', prompt: 'Stop Date' }
]
}
]
}
}
@@template
json = {
collection: {
href: url('/'),
version: '1.0',
links: [
{ rel: 'author', href: 'mailto:mamund@yahoo.com', prompt: 'Author' },
{ rel: 'profile', href: 'http://amundsen.com/media-types/collection/profiles/tasks/', prompt: 'Profile' }
],
template: {
data: [
{ name: 'description', value: '', prompt: 'Description' },
{ name: 'dateDue', value: '', prompt: 'Date Due (yyyy-mm-dd)' },
{ name: 'completed', value: '', prompt: 'Completed (true/false)?' }
]
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment