Representable gem released: Improve your REST representation code!

{{{
The “representable gem”:https://github.com/apotonick/representable helps to keep parsing and rendering representations in one place. Once defined, it gives your model @#to_xml@, @#from_xml@ and more. The initial version was released today, let’s see how it helps *cleaning up your representation code*.

h3. Let’s write a Blog app!

Since your imaginery blog app has a REST API you want to provide a post resource serving and consuming article representations. Here’s a sample XML representation of an arbitrary blog post.


  1
  2011-05-09
  
  
    This is stupid!
  
  
    No, awesome post!
  

Basically, a *post representation contains comments* in addition to some meta data.

h3. The Problem: Two places need to know about your Representation.

In, say, a Rails app, you’d have to tweak the models’ @#to_xml@ method *in order to render an XML representation*. Alternatively, you’d use a Builder template.

If, and only if, you stick to the Rails conventions, @#from_xml@ will work out-of-the-box. Otherwise, *you have to write a manual parser* “as discussed earlier”:http://nicksda.apotomo.de/2011/04/rails-misapprehensions-the-hardest-thing-about-rest-is-working-with-representations/. Note that the @@ tag contains an attribute not compliant with Rails.

You usually end up with some model code, maybe even a template *_and_* a hand-made parser. This distributes representation knowledge over the entire MVC framework. While this won’t kill your mother *it still makes things more work to manage.*

h3. Defining a Representation

The representable gem is designed to prevent you from doing that. *You simply define the representation in one place* and it does the REST _(I still love the word-play)_.

require 'representable/xml'

class Comment #  "@id"
end

The @Representable::XML@ module allows to define *plain properties* (line 6) and *attributes* (line 7).

h3. Nesting Representations

The post representation uses the compositing feature in representable in order to embed comments.

class Post #  :comment, :as => Comment
end

Wow, you can define nested compositions with representable (line 6). This is easy, so how do we work with it?

h3. Rendering Documents

You want to render a document representing your post now.

Post.find(1).to_xml 
  # => "1comment id="1"..."

*Representable takes care of rendering.* No magic included.

h3. Parsing Representations

What if you allow people to POST an XML document to the blog post resource?

@post = Post.from_xml(request.body)
@post.comments
# => "[#]"

Again, representable deserializes the incoming representation and creates the respective objects for you. *Representable doesn’t know anything about databases* or your underlying data layout, though. It just creates fresh instances for compositions making it your job to process it.

h3. Other media types?

Representable comes with XML and JSON support, you just have to mix in the respective module.

@comment.to_json
  # => ""{text => ..."

h3. How does it help?

“Representable”:https://github.com/apotonick/representable is a completely abstract module for rendering and parsing representations and *mapping document fragments to object attributes*. Nothing more.

It makes working with representations _object-oriented_ where you had view templates and parsers before. While representable makes that workflow as simple as possible it also allows _distributing_ your representation code, since it can be pushed into Ruby modules. Maybe it makes sense to use it on both client and server, in Rails and Sinatra?

Representable is also used in Roar to make life easier when *working with REST representations and embedding or consuming hypermedia*. We will discuss how representations and HATEOAS work in the next post. Cheers.
}}}

One thought on “Representable gem released: Improve your REST representation code!

Leave a comment