Class: Restfully::Resource
Overview
This class represents a Resource, which can be accessed and manipulated via HTTP methods.
The #load
method must have been called on the resource before trying to access its attributes or links.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#executed_requests ⇒ Object
readonly
Returns the value of attribute executed_requests.
-
#links ⇒ Object
readonly
Returns the value of attribute links.
-
#properties ⇒ Object
readonly
Returns the value of attribute properties.
-
#session ⇒ Object
readonly
Returns the value of attribute session.
-
#title ⇒ Object
readonly
Returns the value of attribute title.
-
#uri ⇒ Object
readonly
Returns the value of attribute uri.
Instance Method Summary collapse
-
#[](key) ⇒ Object
Description Returns the value corresponding to the specified key, among the list of resource properties.
-
#delete(options = {}) ⇒ Object
Description Executes a DELETE request on the resource, and returns true if successful.
-
#http_methods ⇒ Object
Description Returns the list of allowed HTTP methods on the resource.
-
#initialize(uri, session, options = {}) ⇒ Resource
constructor
Description Creates a new Resource.
- #inspect(*args) ⇒ Object
-
#load(options = {}) ⇒ Object
Description Executes a GET request on the resource, and populate the list of its properties and links
options
:: list of options to pass to the request (see below) == Options:reload
:: if set to true, a GET request will be triggered even if the resource has already been loaded [default=false]:query
:: a hash of query parameters to pass along the request. - #method_missing(method, *args) ⇒ Object
- #pretty_print(pp) ⇒ Object
-
#reload ⇒ Object
Convenience function to make a resource.load(:reload => true).
-
#reset ⇒ Object
Resets all the inner objects of the resource (you must call
#load
if you want to repopulate the resource). - #respond_to?(method, *args) ⇒ Boolean
- #stale! ⇒ Object
- #stale? ⇒ Boolean
-
#submit(payload, options = {}) ⇒ Object
Description Executes a POST request on the resource, reload it and returns self if successful.
- #uri_for(path) ⇒ Object
Constructor Details
#initialize(uri, session, options = {}) ⇒ Resource
Description
Creates a new Resource.
uri
-
a URI object representing the URI of the resource (complete, absolute or relative URI)
session
-
an instantiated Restfully::Session object
options
-
a hash of options (see below)
Options
:title
-
an optional title for the resource
26 27 28 29 30 31 32 |
# File 'lib/restfully/resource.rb', line 26 def initialize(uri, session, = {}) = .symbolize_keys @uri = uri.kind_of?(URI) ? uri : URI.parse(uri.to_s) @session = session @title = [:title] reset end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
Instance Attribute Details
#executed_requests ⇒ Object (readonly)
Returns the value of attribute executed_requests.
11 12 13 |
# File 'lib/restfully/resource.rb', line 11 def executed_requests @executed_requests end |
#links ⇒ Object (readonly)
Returns the value of attribute links.
11 12 13 |
# File 'lib/restfully/resource.rb', line 11 def links @links end |
#properties ⇒ Object (readonly)
Returns the value of attribute properties.
11 12 13 |
# File 'lib/restfully/resource.rb', line 11 def properties @properties end |
#session ⇒ Object (readonly)
Returns the value of attribute session.
11 12 13 |
# File 'lib/restfully/resource.rb', line 11 def session @session end |
#title ⇒ Object (readonly)
Returns the value of attribute title.
11 12 13 |
# File 'lib/restfully/resource.rb', line 11 def title @title end |
#uri ⇒ Object (readonly)
Returns the value of attribute uri.
11 12 13 |
# File 'lib/restfully/resource.rb', line 11 def uri @uri end |
Instance Method Details
#[](key) ⇒ Object
Description
Returns the value corresponding to the specified key, among the list of resource properties
Usage
resource["uid"]
=> "rennes"
51 52 53 |
# File 'lib/restfully/resource.rb', line 51 def [](key) @properties[key] end |
#delete(options = {}) ⇒ Object
Description
Executes a DELETE request on the resource, and returns true if successful. If the response status is different from 2xx or 3xx, raises an HTTP::ClientError or HTTP::ServerError.
options
-
list of options to pass to the request (see below)
Options
:query
-
a hash of query parameters to pass along the request. E.g. : resource.delete(:query => => “value1”)
:headers
-
a hash of HTTP headers to pass along the request. E.g. : resource.delete(:headers => => ‘application/json’)
155 156 157 158 159 160 161 |
# File 'lib/restfully/resource.rb', line 155 def delete( = {}) = .symbolize_keys raise NotImplementedError, "The DELETE method is not allowed for this resource." unless http_methods.include?('DELETE') response = session.delete(self.uri, ) # raises an exception if there is an error stale! (200..399).include?(response.status) end |
#http_methods ⇒ Object
Description
Returns the list of allowed HTTP methods on the resource.
Usage
resource.http_methods
=> ['GET', 'POST']
174 175 176 177 |
# File 'lib/restfully/resource.rb', line 174 def http_methods reload if executed_requests['GET'].nil? || executed_requests['GET']['headers'].nil? || executed_requests['GET']['headers'].empty? (executed_requests['GET']['headers']['Allow'] || "GET").split(/,\s*/) end |
#inspect(*args) ⇒ Object
183 184 185 |
# File 'lib/restfully/resource.rb', line 183 def inspect(*args) @properties.inspect(*args) end |
#load(options = {}) ⇒ Object
Description
Executes a GET request on the resource, and populate the list of its properties and links
options
-
list of options to pass to the request (see below)
Options
:reload
-
if set to true, a GET request will be triggered even if the resource has already been loaded [default=false]
:query
-
a hash of query parameters to pass along the request. E.g. : resource.load(:query => => (Time.now-3600).to_i, :to => Time.now.to_i)
:headers
-
a hash of HTTP headers to pass along the request. E.g. : resource.load(:headers => => ‘application/json’)
:body
-
if you already have the unserialized response body of this resource, you may pass it so that the GET request is not triggered.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/restfully/resource.rb', line 81 def load( = {}) = .symbolize_keys force_reload = !!.delete(:reload) stale! unless !force_reload && (request = executed_requests['GET']) && request['options'] == && request['body'] if stale? reset if !force_reload && [:body] body = [:body] headers = {} else response = session.get(uri, ) body = response.body headers = response.headers end executed_requests['GET'] = { 'options' => , 'body' => body, 'headers' => headers } executed_requests['GET']['body'].each do |key, value| populate_object(key, value) end @status = :loaded end self end |
#pretty_print(pp) ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/restfully/resource.rb', line 187 def pretty_print(pp) pp.text "#<#{self.class}:0x#{self.object_id.to_s(16)}" pp.text " uid=#{self['uid'].inspect}" if self.class == Resource pp.nest 2 do pp.breakable pp.text "@uri=" uri.pretty_print(pp) if @links.length > 0 pp.breakable pp.text "LINKS" pp.nest 2 do @links.to_a.each_with_index do |(key, value), i| pp.breakable pp.text "@#{key}=#<#{value.class}:0x#{value.object_id.to_s(16)}>" pp.text "," if i < @links.length-1 end end end if @properties.length > 0 pp.breakable pp.text "PROPERTIES" pp.nest 2 do @properties.to_a.each_with_index do |(key, value), i| pp.breakable pp.text "#{key.inspect}=>" value.pretty_print(pp) pp.text "," if i < @properties.length-1 end end end yield pp if block_given? end pp.text ">" end |
#reload ⇒ Object
Convenience function to make a resource.load(:reload => true)
109 110 111 112 113 |
# File 'lib/restfully/resource.rb', line 109 def reload = executed_requests['GET']['options'] rescue {} stale! self.load(.merge(:reload => true)) end |
#reset ⇒ Object
Resets all the inner objects of the resource (you must call #load
if you want to repopulate the resource).
36 37 38 39 40 41 42 |
# File 'lib/restfully/resource.rb', line 36 def reset @executed_requests = Hash.new @links = Hash.new @properties = Hash.new @status = :stale self end |
#respond_to?(method, *args) ⇒ Boolean
55 56 57 |
# File 'lib/restfully/resource.rb', line 55 def respond_to?(method, *args) @links.has_key?(method.to_s) || super(method, *args) end |
#stale! ⇒ Object
164 |
# File 'lib/restfully/resource.rb', line 164 def stale!; @status = :stale; end |
#stale? ⇒ Boolean
165 |
# File 'lib/restfully/resource.rb', line 165 def stale?; @status == :stale; end |
#submit(payload, options = {}) ⇒ Object
Description
Executes a POST request on the resource, reload it and returns self if successful. If the response status is different from 2xx, raises a HTTP::ClientError or HTTP::ServerError.
payload
-
the input body of the request. It may be a serialized string, or a ruby object (that will be serialized according to the given or default content-type).
options
-
list of options to pass to the request (see below)
Options
:query
-
a hash of query parameters to pass along the request. E.g. : resource.submit(“body”, :query => => “value1”)
:headers
-
a hash of HTTP headers to pass along the request. E.g. : resource.submit(“body”, :headers => => ‘application/json’, :content_type => ‘application/json’)
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/restfully/resource.rb', line 127 def submit(payload, = {}) = .symbolize_keys raise NotImplementedError, "The POST method is not allowed for this resource." unless http_methods.include?('POST') raise ArgumentError, "You must pass a payload" if payload.nil? headers = { :content_type => (executed_requests['GET']['headers']['Content-Type'] || "application/x-www-form-urlencoded").split(/,/).sort{|a,b| a.length <=> b.length}[0], :accept => (executed_requests['GET']['headers']['Content-Type'] || "text/plain") }.merge([:headers] || {}) = {:headers => headers} .merge!(:query => [:query]) unless [:query].nil? response = session.post(self.uri, payload, ) # raises an exception if there is an error stale! if [201, 202].include?(response.status) Resource.new(uri_for(response.headers['Location']), session).load else reload end end |
#uri_for(path) ⇒ Object
179 180 181 |
# File 'lib/restfully/resource.rb', line 179 def uri_for(path) uri.merge(URI.parse(path.to_s)) end |