Guilhermesilveira's Blog

as random as it gets

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.

About these ads

Written by guilhermesilveira

November 3, 2009 at 6:23 pm

Posted in restful, ruby, soa

Tagged with , , , , , ,

8 Responses

Subscribe to comments with RSS.

  1. Social comments and analytics for this post…

    This post was mentioned on Twitter by caueguerra: quit pretending, use the web for real: restfulie – http://bit.ly/2zqdIE

    uberVU - social comments

    November 4, 2009 at 1:18 am

  2. Wonderfull job. Really beautiful
    You guys are crazy
    I am still trying to diggest all this restful StuffIt

    Rafael

    November 6, 2009 at 11:10 pm

  3. [...] quit pretending, use the web for real: restfulie [...]

  4. Hi Guilherme

    Wonderful piece of work.

    Of the two link types you support, on the whole I prefer to – mainly because with a well-defined link element + open-ended set of link relations, the client can identify new states (resulting from the service provider evolving its offering) based on their hypermedia context, even if it can’t understand their semantics. With style linking, new states will result in wholly new elements, which the client may not even recognize as hypermedia. (More detail on this point here: http://iansrobinson.com/2009/07/16/how-do-you-link/) But very good you support both.

    Kind regards

    ian

    Ian Robinson

    November 17, 2009 at 1:41 am

  5. [...] the server-side RESTfulie gem. The core of the transfer of data between the server and the client can be done in the Atom spec. Which makes for a more open application when you consider the amount of data available in Atom [...]

  6. Is there a reason you didn’t piggy-back off of something like state_machine or workflow for the state transition definitions? Would I be able to swap out one for the other?

    Ryan Riley

    November 30, 2009 at 10:26 pm

  7. Because we needed something simple and small. The most famous ones (aasm) were too big… yep you can swap it, but we will soon give support to rails3 state machine and aasm!

    Regards

    guilhermesilveira

    December 2, 2009 at 9:39 pm

  8. [...] a comment » The first post of the ‘Quit pretending, use the web for real‘ was on how one could use Restfulie for Rails to leverage its application, the second one [...]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: