A CloudKit Service is Rack middleware providing a REST/HTTP 1.1 interface to a Store. Its primary purpose is to initialize and adapt a Store for use in a Rack middleware stack.
Examples
A rackup file exposing items and things as REST collections:
require 'cloudkit' expose :items, :things
The same as above, adding OpenID and OAuth/Discovery:
require 'cloudkit' contain :items, :things
An explicit setup, without using the Rack::Builder shortcuts:
require 'cloudkit' use Rack::Session::Pool use CloudKit::OAuthFilter use CloudKit::OpenIDFilter use CloudKit::Service, :collections => [:items, :things] run lambda{|env| [200, {'Content-Type' => 'text/html'}, ['Hello']]}
For more examples, including the use of different storage implementations, see the Table of Contents in the examples directory.
Methods
public class
public instance
protected instance
Included modules
Attributes
store | [R] |
Public class methods
new
(app, options)
[show source]
# File lib/cloudkit/service.rb, line 34 34: def initialize(app, options) 35: @app = app 36: @collections = options[:collections] 37: end
Public instance methods
call
(env)
[show source]
# File lib/cloudkit/service.rb, line 39 39: def call(env) 40: @@lock.synchronize do 41: @store = Store.new(:collections => @collections) 42: end unless @store 43: 44: request = Request.new(env) 45: unless bypass?(request) 46: return auth_config_error if (request.using_auth? && auth_missing?(request)) 47: return not_implemented unless @store.implements?(request.request_method) 48: send(request.request_method.downcase, request) rescue internal_server_error 49: else 50: @app.call(env) 51: end 52: end
Protected instance methods
auth_config_error
()
[show source]
# File lib/cloudkit/service.rb, line 153 153: def auth_config_error 154: json_error_response(500, 'server auth misconfigured').to_rack 155: end
auth_missing?
(request)
[show source]
# File lib/cloudkit/service.rb, line 141 141: def auth_missing?(request) 142: request.current_user == nil 143: end
bypass?
(request)
[show source]
# File lib/cloudkit/service.rb, line 157 157: def bypass?(request) 158: collection = @collections.detect{|type| request.path_info.match("/#{type.to_s}")} 159: !collection && !request.uri.meta_uri? 160: end
delete
(request)
[show source]
# File lib/cloudkit/service.rb, line 89 89: def delete(request) 90: @store.delete( 91: request.uri, 92: {}.filter_merge!( 93: :remote_user => request.current_user, 94: :etag => request.if_match)).to_rack 95: end
get
(request)
[show source]
# File lib/cloudkit/service.rb, line 56 56: def get(request) 57: response = @store.get( 58: request.uri, 59: {}.filter_merge!( 60: :remote_user => request.current_user, 61: :offset => request['offset'], 62: :limit => request['limit'])) 63: inject_link_headers(request, response) 64: response.to_rack 65: end
head
(request)
[show source]
# File lib/cloudkit/service.rb, line 97 97: def head(request) 98: response = @store.head( 99: request.uri, 100: {}.filter_merge!( 101: :remote_user => request.current_user, 102: :offset => request['offset'], 103: :limit => request['limit'])) 104: inject_link_headers(request, response) 105: response.to_rack 106: end
index_link_header
(request)
[show source]
# File lib/cloudkit/service.rb, line 130 130: def index_link_header(request) 131: index_path = request.path_info.sub(/\/_resolved(\/)*$/, '') 132: base_url = "#{request.domain_root}#{index_path}" 133: "<#{base_url}>; rel=\"index\"" 134: end
inject_link_headers
(request, response)
[show source]
# File lib/cloudkit/service.rb, line 112 112: def inject_link_headers(request, response) 113: response['Link'] = versions_link_header(request) if request.uri.resource_uri? 114: response['Link'] = resolved_link_header(request) if request.uri.resource_collection_uri? 115: response['Link'] = index_link_header(request) if request.uri.resolved_resource_collection_uri? 116: response['Link'] = resolved_link_header(request) if request.uri.version_collection_uri? 117: response['Link'] = index_link_header(request) if request.uri.resolved_version_collection_uri? 118: end
not_implemented
()
[show source]
# File lib/cloudkit/service.rb, line 149 149: def not_implemented 150: json_error_response(501, 'not implemented').to_rack 151: end
options
(request)
[show source]
# File lib/cloudkit/service.rb, line 108 108: def options(request) 109: @store.options(request.uri).to_rack 110: end
post
(request)
[show source]
# File lib/cloudkit/service.rb, line 67 67: def post(request) 68: if tunnel_methods.include?(request['_method'].try(:upcase)) 69: return send(request['_method'].downcase, request) 70: end 71: response = @store.post( 72: request.uri, 73: {:json => request.json}.filter_merge!( 74: :remote_user => request.current_user)) 75: update_location_header(request, response) 76: response.to_rack 77: end
put
(request)
[show source]
# File lib/cloudkit/service.rb, line 79 79: def put(request) 80: response = @store.put( 81: request.uri, 82: {:json => request.json}.filter_merge!( 83: :remote_user => request.current_user, 84: :etag => request.if_match)) 85: update_location_header(request, response) 86: response.to_rack 87: end
resolved_link_header
(request)
[show source]
# File lib/cloudkit/service.rb, line 125 125: def resolved_link_header(request) 126: base_url = "#{request.domain_root}#{request.path_info}" 127: "<#{base_url}/_resolved>; rel=\"http://joncrosby.me/cloudkit/1.0/rel/resolved\"" 128: end
tunnel_methods
()
[show source]
# File lib/cloudkit/service.rb, line 145 145: def tunnel_methods 146: ['PUT', 'DELETE', 'OPTIONS', 'HEAD', 'TRACE'] 147: end
update_location_header
(request, response)
[show source]
# File lib/cloudkit/service.rb, line 136 136: def update_location_header(request, response) 137: return unless response['Location'] 138: response['Location'] = "#{request.domain_root}#{response['Location']}" 139: end
versions_link_header
(request)
[show source]
# File lib/cloudkit/service.rb, line 120 120: def versions_link_header(request) 121: base_url = "#{request.domain_root}#{request.path_info}" 122: "<#{base_url}/versions>; rel=\"http://joncrosby.me/cloudkit/1.0/rel/versions\"" 123: end