Skip to content
josedonizetti edited this page Feb 13, 2011 · 4 revisions

Restfulie

Ruby client

Entry points

Entry points are commonly defined through a resource retrieval or creation request. Restfulie allows you to use both type of entry points through its API.

Resource retrieval entry point

Most systems will create a request retrieval entry point, which can be accessed as:

Response response = Restfulie.at('http://localhost:3000/cities/5').get();`

After that, the xml tree can be accessed and links followed. A typical city hypermedia file would be:

<city>
	<name>Sao Paulo</name>
	<population>
		<size>18000000</size>
		<growth>10</growth>
	</population>
	<link rel="next_largest" href="http://localhost:3000/cities/18" />
</city>

The information can be retrieved through the usual method invocations:

puts city.name
puts "size #{city.population.size} and growth #{city.population.growth}"

And links can be followed as:

next_one = city.next_largest

Note that the client application knows what the rel attribute next_largest means, but does not know what it's value stands for (Rio de Janeiro).

Acessing the web response

In this case, you can access the http response through web_response, i.e.:

city = Restfulie.at('http://localhost:3000/cities/5').get
puts "Response code #{city.web_response.code}"

Parsing a web response

The return of such web_response method is an object of Restfulie::Client::HTTPResponse and allows you to access methods to check whether the request was successful or any other group of response codes:

	city = Restfulie.at('http://localhost:3000/cities/5').get
	puts "Response code #{city.web_response.is_successful?}"
	puts "Response code #{city.web_response.is_client_error?}"

Resource creation entry point

If your server defines an entry point related to a resource creation, you can use the create method as:

resulting_city = Restfulie.at('http://localhost:3000/cities').create(city)

Note that resulting_city seems to be the result of following a 201 response to its given Location header.

Domain model binding example

Create your class and invoke the uses_restfulie method:

class Order < ActiveRecord::Base
	    uses_restfulie
end

One should first acquire the representation from the server through your common GET request and process it through the usual from_* methods:

xml = Net::HTTP.get(URI.parse('http://www.caelum.com.br/orders/1'))
order = Order.from_xml(xml)

or use the restfulie from_web:

order = Order.from_web 'http://www.caelum.com.br/orders/1'

And now you can invoke all those actions in order to change your resource's state:

order.refresh
order.update
order.destroy
order.pay

Note that: * refresh is get * update is put (and you have to put everything back) * destroy is delete * pay (unknown methods) is post

Media type and content negotiation

Restfulie entry point requests can make use of conneg by notifying the server which media type is being sent and which ones can be understood.

Restfulie.as will notify the server about the media type sent, setting the content-type header:

Restfulie.at('http://caelum.com.br/orders').as('application/vnd_caelum_order+xml').create(order)

Restfulie.accepts notify the server of which media types are understood by the client using the Accepts header:

Restfulie.at('http://caelum.com.br/orders/2').accepts('application/vnd_caelum_order+xml').get

Resource format support

Restfulie currently supports full application/atom+xml, xml+atom rel and json+links, besides atom feed and more.

Entry points: POST

In some cases, one wants to access an entry point through a POST request, i.e. adding a new Product to the system:

class Product
	uses_restfulie
	entry_point_for.create.at 'http://www.caelum.com.br/product'
end

product = Product.remote_create Product.new

304 cache support

If a self request is send to another URI, Restfulie will automatically use its Etag and Last-modified informations to execute the request. If the response is 304, it will return the object itself, indicating to the running software that there was no change: saving bandwidth.

Such 304 support is useful for systems where part or most of the requests are related to retrieving information, and even more important in polling systems: every request will not transfer the representation while it has not changed:

order = Order.from_web order_uri
while !order.ready?
	sleep 1
	order = order.self
end
Clone this wiki locally