Guilhermesilveira's Blog

as random as it gets

Posts Tagged ‘rails

REST from scratch

with one comment

This is the first post on a series of examples on how to use Rails and Restfulie on the server side and Restfulie and Mikyung on the client side to create REST based architectures.

On this 10 minutes video you will learn how it is possible to make several representations of one resource available on the server side (xml, json, atom and so on) and one line of code access and parse it on the client side.

This video shows how to access those basic REST api’s as Twitters, CouchDB which are based on http verbs and multiple URIs. The following videos shall demonstrate how to access more advanced REST API’s.

If you have any questions, join us at our mailing list.

Written by guilhermesilveira

April 29, 2010 at 8:43 am

Restfulie 0.5, atom feeds, content negotiation and default controllers

leave a comment »

ATOM FEED

Restfulie 0.5.0 is out and its major new feature is its support to Atom feeds with variable media types.

A feed can be easily rendered by invoking the to_atom method:


@hotels = Hotel.all
render :content_type => 'application/atom+xml',
:text => @hotels.to_atom(:title=>'Hotels', :controller => self)

A collection might contain entries with different media types and each one will be rendered in its own way. The client code works as any other usual client would, note that there is still content negotiation taking place:


hotels = Restfulie.at('http://localhost:3000/hotels').get
puts hotels[0].name
puts hotels[1].name

And using hypermedia to drive our business, deleting an entry will send a DELETE request to that entry’s self URI:


Restfulie.at('http://localhost:3000/hotels').get.each do |h|
h.delete if h.city=="Sao Paulo"
end

In future releases we expect to support atom feed generation (and consuming) through Ratom.

CONTENT TYPE

Another easy to use feature is content type negotiation, which also happens when rendering a single resource:


@hotel = Hotel.find(params[:id])
render_resource @hotel

Users can now extend Restfulie in order to create custom formats (not based on json/xml/xhtml related media types)

CLIENT SIDE

Entry points have been extended and now they can be reached even if there is no class representing the received information in the client side:


support Restfulie.at('http://localhost:3000/cities').create(city)
Restfulie.at('http://localhost:3000/cities/5').get

One can also access the web response:

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

And play with content negotiation:


Restfulie.at(uri).accepts('media-type').get
Restfulie.at(uri).as('media-type').create(something)

DEFAULT CONTROLLERS

In the server side, a generic controller has been created which supports show, delete and create by default.

There is also a new method called render_created that can be used in order to answer a request with a 201 Created response and its resource location.

WEBSITE

Restfulie got its own website and all Ruby docs have been migrated.

Thanks to all the team and collaborators!

If you look carefully, you might find out next week’s upcoming news.

Written by guilhermesilveira

January 7, 2010 at 9:30 am

quit pretending, use the web for real: restfulie

with 8 comments

Resource representation

A simple resource representation in xml could be

<order>
  <product>basic rails course</product>
  <product>RESTful training</product>
  <price>500.00</price>
</order>

It provides information on the order itself, as we are used to. But it lacks providing meta information on anything related to business process: from here, I am unable to go anywhere.

This resource is unable to lead its consumers through possible steps further on a business flow, i.e. creating a payment or cancelling it.

Looking at this resource, it is clear that it is just an usual “structural representation” of something that programmers would code in C: the data and it’s structure: but no possible actions.

Identifying resources

In order to access those resources, one needs to possess its address, its URI.

We use, for example, URIs to identify our courses at Caelum.

The advanced rails training can be accessed through the http://www.caelum.com.br/curso/rr-75-ruby-rails-avancado/ URI and also through http://www.caelum.com.br/curso/rr-75.

Note that there is no need to have an unique URI to resource or resource to URI mapping. In our case, the latter URI redirects to the first one through an http permanently moved response.

Web services

One can understand web services as services which use the web as its infrastructure. The basic step to create a web service is to use http requests to act.

Typical SOA applications will stop its evolution and its use of the web infrastructure here, not profiting from everything else that the web provides.

Resources accessed through the web

Once I have an URI in my hands, and a web service that provides me the resource representation through a web request (typically a GET request), one receives as output the requested resource representation.

Using different HTTP verbs and analyzing the request and result headers and codes, one makes and profits from further usage of the web infrastructures such as caching proxies and fault tolerance assurance due to idempotent methods.

Frameworks and applications, like the one from the spring blog, which provides the first level of web infrastructure usage would be called resource based web services (RBWS) if they were not lacking the use of the most common web aspect: hypermedia.

According to Roy Fieldings, “REST is defined by four interface constraints: identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state.”

Web service based CRUD

Web service based cruds are those ressemblingthe spring tutorial, which maps URIs to resources and allows the usage of different HTTP Verb, headers and return codes to sign actions and return values.

Although being a sign of better usage of the web in order to create web-based services, it is still missing the very best part of our every day life: hyperlinks and hypermedia content.

Doing CRUDs is an everyday task, and doing service based CRUD implementation is a nice and cute functionality that frameworks as rails, spring and vraptor allows us to do.

According to Leonard Richardson model, one can roughly categorize his usage of the web infrastructure based on which use one makes out of it. CRUD over the web is just the first step, and hypermedia support is the following one.

Hypermedia aware resources

Resources supporting hypermedia provide consumers the next steps to follow on an application business flow. It allows the consumer to change the application state as web requests are stateless.

The following code shows an example of xml+hypermedia representation of the same order seen earlier:

	<order>
		<product>basic rails course</product>
		<product>RESTful training</product>
		<refresh>http://www.caelum.com.br/orders/1</refresh>
		<update>http://www.caelum.com.br/orders/1</update>
		<pay>http://www.caelum.com.br/orders/1/pay</pay>
		<destroy>http://www.caelum.com.br/orders/1</destroy>
	</order>

Note that this path is a simple yet powerful way of interacting with your clients. Although its a valid option, one can make use of the w3c atom format as nowadays there are hundreds of important tools atom-aware:

<order>
  	<product>basic rails course</product>
  	<product>RESTful training</product>
  	<atom:link rel="refresh"
          href="http://www.caelum.com.br/orders/1"
          xmlns:atom="http://www.w3.org/2005/Atom"/>
  	<atom:link rel="update"
          href="http://www.caelum.com.br/orders/1" 
          xmlns:atom="..."/>
  	<atom:link rel="pay"
          href="http://www.caelum.com.br/orders/1/pay" 
          xmlns:atom="..."/>
  	<atom:link rel="destroy"
          href="http://www.caelum.com.br/orders/1
          xmlns:atom="..."/>
</order>

Cutting a new gem

Both Jim and Savas have commented on the client simple javascript+html resource+hypermedia (restful?) client that we have created so one could easily test a restful application online.

So me and Caue Guerra at Caelum were ready to move to the next step: getting resource+hypermedia support to rails applications.

SOA applications, due to strange and dark forces, typically demand dozens of developers to built something complex and hard to maintain.

With this in mind, we have developed Restfulie, which is a rails based gem.

It works both on the server and client side making it easier to provide and consume such restful resources.

Requesting a resource

A resource based web services provider – another long name for a partial rest implementation based on roy’s dissertation – can access a resource through the api:

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

Now, one can request its content

 puts order.products

or even invoke those “methods”:

 order.pay payment
 order.cancel
 payment = order.check_payment_info

All those three methods are remote invocations (never forget it!) that access the server executing POST, DELETE, PUT and GET operations, serializing and deserializing xml+atom content (or json, …).

Thats about it. You have consumed a resource representation and acted upon it in two lines of code, moving your resource to another state on your business flow.

Meanwhile, on the server side

Those who want to provider RBWS can easily do it using restfulie by implementing the method following_states as follow:

class Order
 def following_states
 states = [ { : orders, :action => :show } ]
 states << : orders, :action => :destroy} if can_cancel?
 states << : orders, :action => :pay, :id => id} if can_pay?
 states
 end
end

And in a 6 lines long method, one has implemented a full RBWS provider: all invocations to to_xml and to_json will serialize atom or rel based links to those state transition services.

Live examples

You can try the server side ordering application online and a sample client side application live at heroku.

In order to fully test those systems, follow the “Try it online” directions on the Restfulie website.

Concluding

This post gives a basic idea on resources, web based services and how one can really use the web to profit from its already existing infrastructure.

While some RBWS providers already use all this knowledge, most of the frameworks that we see today focus on “restful” meaning “accessing a resource through its URI and http verbs”. There is more to the web than just getting, posting and uris. There is a whole world hidden behind links so… let’s quit pretending and start using the web infrastructure for real.

Written by guilhermesilveira

November 3, 2009 at 6:23 pm

Posted in restful, ruby, soa

Tagged with , , , , , ,