Posts Tagged REST

Ruby On REST 6: Pagination With Roar

Friday, May 18th, 2012

Yo! How’s it folks? Let’s do some more REST today. I’d like to show how easy it is to have paginated REST documents with Roar while using a nifty feature introduced in version 0.10.2.

What’s In That Fruit Salad, Sir?

Since we keep having fruit salads in the last posts I wanna write a service to display the ingredients of a particular fruit bowl in a list. Not just a list of fruits, a paginated list of fruits.

Let’s GET it.

POST http://bowls/1/fruits?page=1

Considering two fruit items per page this document will be returned.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{"total_entries":5,
 "links":[
  {"rel": "self",
   "href":"http://bowls/1/fruits?page=1"},
  {"rel": "next",
   "href":"http://bowls/1/fruits?page=2"}],
 "items":[
  {"title":"Apple",
   "links":[{"rel":"self",
              "href":"http://fruits/Apple"}]},
  {"title":"Orange",
   "links":[{"rel":"self",
             "href":"http://fruits/Orange"}]}
  ]
}

Ignore the items for now, the interesting part here are the pagination elements in the first lines. What we have here is:

  • The number of total ingredients in the bowl (line 1).
  • The obligatory self link (line 3-4).
  • A link guiding us to the next page (line 5-6).

Wow! Code?

The backing code in this service endpoint could look like the following snippet. As always, the code used to create this example can be found on github.

1
2
3
4
5
6
bowl = Bowl.find(1)
page = bowl.fruits.paginate(:page => 1, 
  :per_page => 2)
 
page.extend(BowlPageRepresenter)
page.to_json(:bowl => @bowl)

First task is to retrieve the viewed bowl (line 1). I use a static id in this example, feel free to replace it with something like params[:id] in your code. Next, I use paginate from the famous will_paginate gem to get a paged subset of the included fruits. Again, the :page parameter should be refering to a variable, whatever (line 2-3).

Then I simply extend the collection (line 5) since it is a valid Ruby object and call to_json to render the list (line 6). Keep in mind that we pass the :bowl instance into the render method as an argument.

The Bowl Representer Can Do Pagination

To fully understand that example we need to look at the representer now.

module BowlPageRepresenter
  include Roar::Representer::JSON
  include Roar::Representer::Feature::Hypermedia
 
  property :total_entries
  collection :items, :extend => FruitRepresenter
 
  link :self do |opts|
    bowl_url(opts[:bowl], :page => current_page)
  end
 
  link :next do |opts|
    bowl_url(opts[:bowl], :page => next_page) \
      if next_page
  end
 
  link :previous do |opts|
    bowl_url(opts[:bowl], :page => previous_page) \
      if previous_page
  end
 
  def items
    self
  end
end

Instead of refering to line number I’ll use code excerpts now. Do you like that better?

  property :total_entries

In a paginated collection we got the total_entries method as described in the will_paginate API docs. To give our REST consumer a hint about the total amount of ingredients we can simply define a property after that.

  collection :items, :extend => FruitRepresenter

To render the actual items in the doc we extend each fruit with the FruitRepresenter as we learned in an older post. Note that Roar will use the items method to retrieve the collection of fruits.

  def items
    self
  end

Since we are already a collection all we have to do is return self – roar will iterate the paginated collection, extend each element with the FruitRepresenter and render the items.

A Cool New Feature!

The links to the next pages are defined using Roar’s hypermedia feature.

  link :next do |opts|
    bowl_url(opts[:bowl], :page => next_page) \
      if next_page
  end

Two things happen here. First, note that this link is conditional. If next_page, another API method for a will_paginate collection, is evaluated to false, this link won’t be rendered.

Second, we use a new feature of Roar here to access variables passed into to_json. Remember how we called the render method?

page.to_json(:bowl => @bowl)

Right, we pass in some values from the outside since we don’t have access to the actual bowl instance within the represented collection. These parameters are accessible in the link block parameters. Isn’t that nice? I like it.

These few lines of code make it easy to render a paginated collection into a valid REST document.

Writing A Generic Pagination Representer

Now that all paginated documents share attributes (total entries, next and previous link, the self link, etc) why not abstract that into a generic representer? Most of the code can be reused.

module PaginationRepresenter
  include Roar::Representer::JSON
  include Roar::Representer::Feature::Hypermedia
 
  property :total_entries
 
  link :self do |opts|
    page_url(opts[:model], :page => current_page)
  end
 
  link :next do |opts|
    page_url(opts[:model], :page => next_page) \
      if next_page
  end
 
  link :previous do |opts|
    page_url(opts[:model], :page => previous_page) \
      if previous_page
  end
 
  def items
    self
  end
 
  def page_url(*)
    raise "Implement me."
  end
end

All I did was calling a generic page_url method that must be implemented by the using representer. Also, I no longer use the :bowl keyword but a more generic :model, ok?

Nothing in this abstract representer module is related to stinky fruit salads anymore. Man, this thing could even represent a sixpack of beers (a domain I do prefer over fruits).

To inherit we just include the abstract into the concrete representer.

module BowlPageRepresenter
  include Roar::Representer::JSON
  include PaginationRepresenter
 
  collection :items, :extend => FruitRepresenter
 
  def page_url(*args)
    bowl_url(*args)
  end
end

That is cool. All we have to do is defining the concrete items collection and how to compute the pagination URLs. Come on guys, that is easy!

Remember, we changed the incoming parameter, so the rendering call must change, too.

page.to_json(:model => @bowl)

Cheers!

It is Friday eve, have a wonderful weekend and let me know how it was!

Why Is The Representer Called Representer?

Friday, May 11th, 2012

A number of users (hundreds, maybe thousands) have been asking why representers are called representers and not “representations”. It is a valid question and since I spent decades to come up with this term I’d like to discuss the decision here quickly.

What Is A Representation?

A representation in the REST style – and this is what we’re talking about here – is a document describing a resource. Actually, it is illustrating the current state of that resource, usually with property/value lists, embedded resources and pointers to other resources using hypermedia. The format is not relevant in this context, it could be JSON, HTML or the accursed XML.

It is a document you can pull on your hard disk, save it and pop it out on christmas again. Did I mention that I’m writing this post in a cafe facing the beach with a cold Castle in my hand, blinded by the sun and intrigued to jump back into the waves?

What Is A Representer?

Now, on the other side, we have the representers as introduced by the roar gem. Those guys are Ruby code and out in the wild you might find them written as modules, mostly. A representer may look like the following beautiful snippet.

module FruitRepresenter
  include Roar::Representer::JSON
 
  property :title
 
  link :self do
    fruit_url(self)
  end
end

In short, injected into an object that very instance gets capable of rendering a document from its current state and updating its attributes by parsing a document – following the syntax definition from the representer module.

Isn’t That A Presenter?

Ok. A representer module enhances an object by enriching it with new methods. Isn’t that a presenter, that’s what Jason wants to know.

The idea seems interesting, but I’m confused as to how this is different from a traditional presenter or decorator?

What I learnt from the tech panel OOP vs. Rails at the fantastic Wroclove.rb conference – if I listened to Steve Klabnik correctly – is

  • Decorator is a pattern that adds methods and optional state to an object. If I write a module introducing currency conversion methods into a float object it’s a Decorator.
  • Presenter seems to be a subset of Decorator which adds functionality for, well, presenting the object. That could be an ActiveRecord row instance extended with methods to serialize to JSON.

Steve, is that true?

So why is a representer not a presenter? Well, the answer is: it is a presenter, but it is more. The rendering behaviour as found in e.g. to_json in the representer is clearly presentation logic. However, the parsing mechanics are definitely beyond the scope of a Presenter. I agree that a representer still is a Decorator (adding functionality, great).

Why Isn’t It Called Representation?

People are worried about the “ter” ending (as in Terminater). Scott got justified concerns that choosing “representer” as opposed to “representation” has roots in my Ruby hipster attitude.

So, if “Representer” is a reflection of the popularity of “Presenter”,it would seem to be an example of throwing good money after bad. If “Presenter” is already somewhat tainted with inaccuracy, then so would “Representer”.

In an email he is refering to that confusion caused by the Presenter pattern name in the Ruby community (just google presenter + ruby if you can’t follow now). So his proposal

The Fruit class is a “Representation”, not a representer.

Oh no, call it representation!

And as if that wasn’t enough critics on MY pattern name, Charles Lowell, author of rubyracer, saviour of the poor and knight of the dark, reinforces the representation argument.

personally I prefer FooRepresentation as opposed to FooRepresenter, but that’s just me. It implies that “this defines what the representation is“, as opposed to “This defines is how the representation is generated”

That sounds conclusive to me and lead me to reflecting the terms once again.

Now What, Representer or Representation?

So, maybe the the concrete representation declaration (the module using roar and defining properties and hyperlinks) is a representation whereas the underlying abstracted module is a representer?

I speaking for myself still prefer the name representer as we not only define syntax and semantic of a representational document but also add functionality to the represented object as it gets enriched with e.g. to_json and from_json. That as-it makes the FruitRepresenter module “active” and justifies the “ter” ending, just as in “Terminater”, ok?

Roar 0.10 with JSON-HAL Support and Representable 1.1.6 Released

Friday, April 20th, 2012

Just a quick round-up for new things in the Roar world. Here we go!

Roar Speaks JSON-HAL Now!

In the last Ruby on REST post I explained the basics of the hypermedia type HAL which gives your document nesting and linking semantics. This promising format is now supported by Roar.

By including the Representer::JSON::HAL module in your representer it will render and parse documents according to the HAL standard.

module OrderRepresenter
  include Roar::Representer::JSON::HAL
 
  property :id
  collection :items,
    :class => Item, 
    :extend => ItemRepresenter,
    :embedded => true
 
  link :self do "http://orders/#{id}" end
end

Links will now be pushed into the _links property. Also note the new :embedded option which will key the nested property under _embedded. And all that just by including a module – that’s the power of representers.

Better Links in JSON

Some users asked for another link format when not using the HAL representer. Usually links are handled like this.

"links":[
  { "rel":  "self", 
    "href": "http://orders/42"},
  { "rel":  "items", 
    "href": "http://orders/42/items"}
]}

This is just a format I came up with when writing Roar. Now, if you include Representer::JSON::HAL::Links in your representer, links will be rendered and parsed a bit different.

"links": { 
  "self":  {"href": "http://orders/42"}, 
  "items": {"href": "http://orders/42/items"}
}

Here, links is a hash keyed by rel – very handy on the client side.

Also, you can now include more attributes in links.

link :rel => :self, :title => "That's me!"

Just provide a hash listing the attributes.

Representable Got Conditional Properties!

Last but not least, representable, the underlying mapping gem of Roar got a new option in the 1.1.6 release. :if allows you to define blocks that are evaled when parsing or rendering (“representing”, yo!) the object. If the proc returns false, the property is ignored.

property :state, :if => lambda { authorized? }

The block is executed in instance context allowing you to access instance methods and whatever else you need. Go for it!

Ruby On REST 5: Learn Hypermedia By Making Fruit Salad

Tuesday, March 27th, 2012

Let me start this post by quoting something smart.

REST [is an] architectural style for distributed hypermedia systems”

That actually is the first line, chapter 5 of Roy Fielding’s thesis about REST. I gave a couple of talks last year about hypermedia and the misunderstandings in REST in the Rails world and this post tries to sum up with that by focusing on the hypermedia aspect of this architectural concept.

Challenge: Make Fruit Salad!

In the last posts we discussed using the Roar gem for designing and implementing REST systems in Ruby. We were using fruits and bowls as an exemplary domain – let’s keep up with that and fix a fruit salad today.

As a first step it makes sense getting a bowl for all the ingredients. In our REST system, we just POST to the bowls URL.

POST http://bowls
Content-type: application/json
------------------------------
{"location": "desk"}

The request body contains a minimal document specifying the location for the created bowl. Here’s what we get back.

{"location":"desk",
 "fruits":[],
 "links":[
  {"rel":"self",  "href":"http://bowls/desk"},
  {"rel":"fruits","href":"http://bowls/desk/fruits"}
]}

By reading this I figure out that the bowl on my desk was created, but doesn’t contain any fruits, yet. Also, these “links” seem understandable, while self might point to the bowl resource itself the fruits link probably directs to a collection resource listing all the ingredients in that very bowl.

Looks as if a URL gets a “meaning” by specifying a rel attribute with it.

I infered all that by intuition, as JSON is a pretty simple representation format. And this is the first problem when trying to understand hypermedia. JSON as it doesn’t include any semantics, the links are, well, useless as they’re not understandable to machines. What we need is a hyper-media type. Get it on!

What Is A Media Type, Sir?

A concept called media type gives both syntax and semantics to a document. It is important to understand that a simple media type like JSON doesn’t define anything. It just provides a medium (or format) to encode information.

Why not put it that way: JSON and XML are like primitive communication mechanics. Where XML uses smoke signals for exchanging messages, JSON is human voice. A poor example.

However, listening to my voice doesn’t mean you understand what I’m saying. Reading JSON is like listening to my sounds, but the noize might not make sense to you. Ok?

The media type is like a language. You understanding the media type “english” and me speaking (JSON) in english (media type) makes us happy chatters. And suddenly, a series of sounds turn into “Would you like another beer?”. You understand me since you know the syntax and the semantics of my sounds. That is a media type!

Now That We Understand Hypermedia, What To Do With It?

Instead of using plain, dumb JSON I’d like to introduce a real hypermedia format called HAL which is “specifically for exposing RESTful hypermedia APIs”.

POST http://bowls
Content-type: application/hal+json
------------------------------
{"location": "desk"}

Note that we used the application/hal+json content type desparately hoping the web service understands this media format. Check the response.

{"location":"desk",
 "_embedded":{"fruits":[]},
 "_links":{
  "self":  {"href":"http://bowls/desk"},
  "fruits":{"href":"http://bowls/desk/fruits"}
}}

It obviously does, and now the links are encoded a little bit different, following the HAL standard. While this doesn’t make a real difference for you human being, it changes a lot in machine context. By using this media format, we added semantics: Now, the HAL-aware client knows that links can be found at the _links key, that they’re keyed by rel and so on.

Think about it briefly. Growing up with human voice you understood JSON before. However, now that you learned HAL, you understand all the bits and pieces in the document just by applying the specification rules.

I’m Still Hungry!

Sorry for that detailed discussion about hypermedia types, I’m really getting hungry as well, so let’s add some fruits to the bowl.

POST http://bowls/desk/fruits
Content-type: application/hal+json
------------------------------
{"title": "Apple"}

An apple a day keeps the doctor away. Assuming it is sufficient to post this mini JSON document to the fruits URL I add an apple to my salad. Did that work?

GET http://bowls/desk
Content-type: application/hal+json
------------------------------
{"location":"desk",
 "_embedded":{
  "fruits":[
   {"title":"Apple",
    "colors":[],
    "_links":{"self":{"href":"http://fruits/apple"}}
  }]  
 "_links":{
  "self":  {"href":"http://bowls/desk"},
  "fruits":{"href":"http://bowls/desk/fruits"}}
}

Yeah! I can see an apple inside the _embedded key, which is HAL’s way to nest resources in representations. Also, the apple contains a link again pointing to its resource.

It is needless to note that I could go on like this and POST more fruits to the fruits collection resource in order to enrich my delicious salad.

What Did I Just Do?

This brief example was brief. Nevertheless, it demonstrated the use of hypermedia. Here’s what I did.

  1. First, I POSTed to http://bowls to create a bowl.
  2. The returned document points me to its fruits resource.
  3. To add fruits, I POST to http://bowls/desk/fruits as defined in the representation.
  4. I retrieve the updated bowl by following the self URL of the bowl.

Well, what’s so special about that?

The key is, I didn’t compute any URL except the initial URL in (1.) – this is what we call the single entry point. No knowledge about follow-up URLs was needed to operate my fruit salad API. Everything I need to know is included in the representations.

Actions (aka URLs) that are meaningful in the current application state can be found in the document without any need to build URLs myself. This concept is called HATEOAS – a beautiful name… for a cat.

Thou Shall Not Make Any Fruit Salad Without Hypermedia!

Roy Fielding, the inventor of REST, states that your API is RESTFUL if and only if it is hypermedia-driven! In my words, that’ll mean no URL code should be hard-wired into your REST client – except for the single entry point URL. Any additional resource must be extracted from returned documents. And, hey, this is the very reason why REST is defined as a style for “distributed hypermedia systems”.

How that works with the Roar gem is subject to discussion in my upcoming next post! Stay tuned and enjoy life!

Ruby on REST 4: Using Representers in Rails

Monday, March 5th, 2012

It has been a while since I blogged about Roar and it’s representers – beautiful South Africa kept me from doing my homework. Nevertheless, in the meantime, the new roar-rails gem emerged bringing together Rails and Roar in a very easy going way. I’d like to describe how this gem works by implementing a fruit and fruit bowl backend service following the examples from the last posts.

Oh, and before I forget mentioning, the Rails example app is available on github where I will keep adding examples from the Ruby On REST blog series.

Setting It Up…

To make things happen it is necessary adding the roar-rails gem to your Gemfile.

gem 'roar-rails'

As we wanna use Rails’ URL helpers in our representers we have to add one line to the environment.

  config.representer.default_url_options = 
    {:host => "yum.my"}

Rendering Fruits, Done Right.

For simplicity let’s assume our Fruit model has the following underlying, highly complex database scheme.

  create_table "fruits" do |t|
    t.string   "title"
  end

Tough stuff, isn’t it?

Clients might want to retrieve fruit representations, that’s why we start with a functional test for handling GET requests on the FruitsController.

class FruitsControllerTest < ActionController::TestCase
  include Roar::Rails::TestCase
 
  test "GET returns fruit document" do
    get :show, :id => 1, :format => :json
    assert_body "{\"title\":\"Apple\",\"links\":[
      {\"rel\":\"self\",
       \"href\":\"http://yum.my/fruits/Apple\"}]}"
  end

Including the Roar::Rails::TestCase module into the test gives us a couple of new or changed methods. One of those is assert_body and all it does it testing equality of the passed string and the last returned document. This test verifies our REST representations are rendered correctly.

Here’s the handling code in the FruitsController.

class FruitsController < ApplicationController
  include Roar::Rails::ControllerAdditions
  respond_to :json
 
  def show
    fruit = Fruit.find_by_id(params[:id])
    respond_with fruit
  end

This is all very familiar code! But, wait… what happens here behind the scenes? The inclusion of the ControllerAdditions module activates a new responder which will take care of the JSON-rendering that is invoked inside respond_with. So, behind the curtain, the following is executed.

fruit.
  extend(FruitRepresenter).
  to_json

The roar-rails gem infers the representer name used for rendering.

The Fruit Representer

Now, where is that representer? It lives in the app/representers directory and its implementation is quite simple.

module FruitRepresenter
  include Roar::Representer::JSON
 
  property :title
 
  link :self do
    fruit_url(title)
  end
end

All it does is defining the title property and the self link. Please note that we can simply use URL helpers here, making it pretty easy to include hypermedia in our representations.

Amazing! This is all the code needed for rendering fruit documents, including hot hypermedia and handling GET requests. Now, what do we need to consume incoming documents, in, let’s say a POST request?

Eat More Fruits!

To create new fruits in our backend service we’d need to accept POST requests. Test it.

class FruitsControllerTest < ActionController::TestCase
  # ...
 
  test "POST creates fruit" do
    post :create, "{\"title\":\"Orange\"}", 
      :format => :json
 
    assert_body "{\"title\":\"Orange\",\"links\":[
      {\"rel\":\"self\",
      \"href\":\"http://yum.my/fruits/Orange\"}]}"
  end

Again, we use assert_body to assure the resource returns the freshly created representation of the orange. Now, check the post: The second argument is the actual JSON document sent by the client. This is an API change. We no longer pass hashes to the “POST”, but use real documents to test our services.

The consuming controller action is hilariously simple as well.

class FruitsController < ApplicationController
  # ...
  def create
    fruit = Fruit.new.
      extend(FruitRepresenter).
      from_json(request.body.string).
      save
 
    respond_with fruit
  end

It creates a new Fruit instance, mixes in the respective representer, parses the incoming JSON document and updates the fruit’s attributes in the #from_json method and then renders the created model.

In the upcoming version of roar-rails, this code can also be written like:

class FruitsController < ApplicationController
  # ...
  def create
    fruit = consume(Fruit).
      save
 
    respond_with fruit
  end

The consume method provided by roar-rails is still under discussion – feel free to add comments to this post if you have a groundbreaking idea how to simplify the consumption steps!

Fruits On This Planet – Unite!

If that was to easy for you, and I bet it was, why not implement the fruit bowl as well. Consider this model class.

class Bowl < ActiveRecord::Base
  has_and_belongs_to_many :fruits
end

Instead of wasting time with the rendering test and parsing code – which is identical to the fruit code – we jump directly into the parsing test.

class BowlsControllerTest < ActionController::TestCase
  include Roar::Rails::TestCase
 
  test "POST creates bowl with fruits" do
    post :create, 
      "{\"fruits\":[{\"title\":\"Orange\"}]}", 
      :format => :json
 
    bowl = Bowl.find(:last)
    assert_body "{\"fruits\":[
      {\"title\":\"Orange\",\"links\":[
        {\"rel\":\"self\",
        \"href\":\"http://yum.my/fruits/Orange\"}]}],
      \"links\":[
        {\"rel\":\"self\",
        \"href\":\"http://bowls/#{bowl.id}\"}]}"
  end

Sometimes I wish my blog was less narrow.

In the test, an initial bowl document is POSTed to the resource. We expect a fresh bowl representation containing fruits as the response.

Let’s look at the controller action to understand how representers work in a nested setup. Speaking of nesting, here’s the representer responsible for rendering and parsing bowls.

module BowlRepresenter
  include Roar::Representer::JSON
 
  property :location
 
  collection :fruits, 
    :class => Fruit, 
    :extend => FruitRepresenter
 
  link :self do
    bowl_url(id)
  end
end

In addition to the location property the collection defines a nesting fruits. The BowlRepresenter now knows that the collection contains Fruit instances that must be represented with the according FruitRepresenter. We already discussed that in one of the last posts.

Here’s the controller action using that representer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class BowlsController < ApplicationController
  # ...
 
  def create
    bowl = consume(Bowl)
 
    # puts bowl.fruits.inspect
    bowl.fruits = bowl.fruits.collect do |f|  
      Fruit.find_by_title(f.title)
    end
 
    bowl.save
 
    respond_with bowl
  end

I simply assume the consume call already works. Then, what is that loop? Well, when parsing the incoming document, the bowl representer creates a new Fruit instance for every fruit in the collection. If line 7 would be uncommented, it would output the following.

[#<Fruit id: nil, title: "Orange">]

That is, before we reset the collection manually. The representer doesn’t know anything about the database – it just maps a fruit representation in the document to a fresh Fruit instance. This is why there is no id set, yet. We have to do that ourselves (lines 8-10). What might look clumsy to you is simplicity – it’s up to you how to map objects to database records.

Conclusion – For Now?!

Come on, it is easy to use representers in your Rails backends using the roar-rails gem. It helps you rendering documents and makes it quite easy to have object-oriented access to a parsed incoming representation – under Rails-conditions.

And, as always, this is just a start. Open source lives from discussion and criticism, so feel free to use the comments form below. In the next post I’ll discuss writing paginated collections using representers. Have a nice day!

Ruby On REST 3: One Model, Multiple Representations!

Monday, January 9th, 2012

Happy New Year to all my fellow readers! I hope you had a good party!

In this post I wanna clarify why representers in Roar are much more versatile than one might think at first sight.

Model != Resource

I know, Rails teaches us that every resource is a model with exactly one representation. This is wrong. Not only can a resource be just anything, ranging from simple 1-to-1 mappings of database rows to virtual models like a workflow but also can your business models be represented in completely different contexts.

Let’s get back to our fruity example to learn more about this.

orange = Fruit.find_by_title("Orange")
orange.extend(FruitRepresenter).to_json
#=> {"title":"Orange","colors":["orange"]}

In the last discussion we had a Fruit and a Bowl model which were represented in their respective resources. While the fruit just contains some properties the bowl was a composition thereof. This is pretty “rails-conform” (I use this word with a negative undertone) and can simply be abstracted to hundreds of projects where people expose users, blog posts or events in their resources. This is what we call a 1-to-1 mapping of model to resource.

Let’s have some Booze!

We wrote a simple FruitRepresenter for mapping apples, lemons or oranges to documents, and we had the BowlRepresenter to provide documents for fruit collections. That was nice. But you can do more with fruits. Why not open a distillery and make some good booze from pears or grapes?

What that means for our REST API is that we have to represent fruits as ingredients. We also want to document what fruits are contained in a bottle of schnaps.

module IngredientRepresenter
  include Roar::Representer::JSON
 
  property :title
  collection :tastes_like
end

The new IngredientRepresenter looks a bit similar to our FruitRepresenter, however, it represents a fruit in another context.

pear = Fruit.find_by_title("Pear")
pear.extend(IngredientRepresenter).to_json
#=> undefined method `tastes_like'

An exception. While the pear exposes a #title method it does not have a #tastes_like method. Why did I do that? I wanted to emphasize that the representer doesn’t guess anything from the represented object (the pear). It is up to the fruit to provide decent accessors like the #tastes_like reader. No magic or implicit semantics in Roar. And this is a good thing.

Another Context, Another Module.

We could easily push the missing methods into the IngredientRepresenter itself, but we will learn in an upcoming post that it is better to provide additional accessors in a separate module.

module Ingredient
  def tastes_like
    TastesLike.query(title) # returns array.
  end
 
  def tastes_like=(*)
  end
end

In the reader, we query the world-famous TastesLike™ web service. Since we don’t need a writer, the second method ain’t doing nothing.

pear.extend(Ingredient, IngredientRepresenter).to_json
#=> {"title":"Pear","tastes_like":["pear","mango"]}

Cool, this is a fruit represented in a completely different context. What about the parsing, does that work, too?

apple = Fruit.new
apple.extend(Ingredient, IngredientRepresenter)
apple.from_json("{\"title\":\"Apple\",
  \"tastes_like\":[\"Pear\",\"Apple\",\"Mango\"]}")
#=> #<Fruit title="Apple", colors=[]>

Yepp, parsing an ingredient and mapping it to a fruit also works fine.

Fruits in a Bottle.

Let’s see how collections can be represented in different contexts.

module BottleRepresenter
  include Roar::Representer::JSON
 
  collection :fruits, :class => Fruit, 
    :extend => [Ingredient, IngredientRepresenter]
end

The bottle representer knows that it’s composed of Fruit instances. It does use the IngredientRepresenter for parsing and rendering, though. BTW, if you don’t like the long :extend assignment you are free to “hard-include” the modules directly in your models.

Summary

So what we’re doing here is having one model used in two completely different contexts: the conventional “fruit” context and the “ingredient” context. Imagine you’d be doing this with #as_json and different hash-parsing algorithms in your controllers – good luck.

Ruby On REST 2: Representers and the DCI Pattern

Friday, December 16th, 2011

We talked about Representers earlier last week. Today, I wanna describe DCI and how it fits perfectly together with representers in Roar.

What is DCI?

For years we’ve been taught that “Fat Models, Skinny Controllers” is the way to organize code. Push all your domain code into your ActiveRecord classes. Many people, including me, agree that this is bullshit. This leads to bloated classes, usually combined with one or two object instances taking care of an entire workflow (aka request).

DCI is an architectural pattern that makes the model “fat-on-demand”: Data objects are enhanced with roles at runtime, but only when needed.

The DCI pattern consists of three concepts.

  1. Data objects are supposed to contain application data. Nothing else. This would be your ActiveRecord row instance, but without any predefined behaviour. Just data.
  2. Context objects define what is done in the current workflow. In Rails, a controller running an action could be a context object.
  3. Roles are behaviour for data objects in a particular context. In Ruby, a Rails controller could mixin a module (a “role”) into an empty model row and thus let it process something.

Hooray for DCI – But Why?

Now the thing is, I absolutely hate to hype something (except stuff I did, of course). However, DCI makes code better maintainable, easier to follow and way easier to test. Period.

BTW, did you already check out my new Roar gem? It’s hip!

Think of a classical model found in many Rails applications with maybe one hundred methods. Or fifty. Fifty methods to interfere with each other. In a DCI setup, an object has a limited behaviour scope. The limited knowledge makes it easier to debug and predictable.

One Model, Multiple Faces

Since representers are modules they fit perfectly into the DCI approach, making them roles. Let’s consider the fruit representer from last week, again.

require 'roar/representer/json'
 
module FruitRepresenter
  include Roar::Representer::JSON
 
  property :title
  collection :colors
end

You still can include this representer into its “host” class directly.

class Fruit
  include Roar::Representer
  include FruitRepresenter
end

The problem now is that the Fruit class is limited to one representation, only. Forever and a day you may only render one particular representation. The key about representations, however, is that one model may be represented by multiple, yeah, representations.

Now, back to the start, let’s assume the Fruit class is some empty ActiveRecord class without any prior knowledge of representations at all.

class Fruit < ActiveRecord::Base
end
 
lemon = Fruit.from_json("{\"title\":\"Lemon\"}")
#=> undefined method `from_json' for Fruit:Class

Yeah, there is no #from_json class method.

Representers On DCI

In order to use the DCI approach, we first need an instance. Here’s how the lemon instance, and only this instance, can be extended with the fruit representer.

lemon = Fruit.new.extend(FruitRepresenter)
lemon.from_json("{\"title\":\"Lemon\"}")
lemon.title #=> "Lemon"

Awesome! The built-in Ruby #extend method makes the lemon instance aware of its representation and mixes in #from_json and friends.

Naturally, this works in both ways.

orange = Fruit.find_by_title("Orange")
orange.extend(FruitRepresenter).to_json
#=> {"title":"Apple","colors":["green"]}

The mixed-in representer also lets us render the JSON document.

Gimme Complexity!

On a flat level with single objects, this works out-of-the-box with recent Roar/representable versions. Problems arise when we have nested setups.

module BowlRepresenter
  include Roar::Representer::JSON
  include Roar::Representer::Feature::Hypermedia
 
  property :location
  collection :items, :as => Fruit,
    :extend => FruitRepresenter
 
  link :self do
    "http://bowl/#{location}"
  end
end

Using the :extend option we can give representable a hint about the representer to use when rendering/parsing contained objects.

And, hey, this works.

empty_bowl = Bowl.new
empty_bowl.extend(BowlRepresenter)
emtpy_bowl.from_json("{\"location\":\"kitchen\", \
  \"items\":[{\"title\":\"Lemon\",\"colors\":[]}]}")
 
puts empty_bowl.items.first.title #=> "Lemon"

Discussion Needed!

Having representers on an object level makes the whole thing really clean and versatile. You can test document rendering and parsing without polluting classes. And you can have a FruitRepresenter, a RottenVegetableRepresenter and what else you like for your orange instance. BTW, oranges ain’t no vegetables.

We still discuss about the API and need your opinion. Right now, we got this

collection :items, :as => Fruit,
    :extend => FruitRepresenter

Here, :as describes the class that encapsulates the contained data. The :extend option helps representable to find the correct module for the nested item. Now, what about this?

collection :items, :class => Fruit,
    :module => FruitRepresenter

Does that make sense? These options really just describe what’s on the right side of the hash rocket. Thanks to Scott for discussion here. Now, tell us your story!

Ruby On REST: Introducing the Representer Pattern

Wednesday, December 7th, 2011

This post introduces the new Roar gem, a framework-agnostic REST framework for Ruby that puts focus on object-oriented REST documents.

More object-orientation?

The calls for more object-orientation in Ruby frameworks are growing ever louder. Most web frameworks, like Rails, come with a nice database abstraction, a Rack-like HTTP endpoint, routing, and a template engine. It’s the lack of additional abstraction layers that make many programmers ask for “more OOP”.

Already yawning? Yeah, I wrote about that earlier this year. Let’s talk about working solutions now. Let’s talk about REST.

REST is about Documents!

REST is not only about pretty URLs. The problem ain’t URLs at all. Most frameworks have a decent routing layer to connect resource logic (aka controllers) to URLs. However, the key of REST is pushing documents between clients and servers, so why don’t we finally focus on documents?

It’s the document parsing, processing and rendering that makes our heads spinning.

Note: I here use the terms representation and document interchangable just because I can!

Parsing and Processing

Both clients and services have to parse incoming documents. Consider this JSON document.

{"title":  "Lemon",
 "colors": ["green"]}

This could be sent to a resource to create a new fruit, or be retrieved by some client which issued a GET request.

In Rails, and many HTTP gems, this is automatically parsed using a JSON gem.

params = JSON['{"title":  "Lemon",
                "colors": ["green"]}']
 
params["title"] #=> "Lemon"
params["colors"][0] #=> "green"

We’re using a hash access to read properties from that document. This is handy! Now, assume the sender forgot to include the colors.

params = JSON['{"title":  "Lemon"}']
 
params["colors"][0]
#=>NoMethodError: undefined method `[]' for nil:NilClass

An exception, shit! While processing the parsed document (aka hash), we have to take care of missing keys, wrong types etc. We as the consumer have to know about all the pitfalls with this particular document.

Rendering

Now that our parsing and processing code is finished, how do we render outgoing representations? We could use #to_json.

@lemon.to_json(:only => [:title, :colors])

Being a quick solution for rendering small models this approach hits the wall when we have nested models but still want a plain JSON representation, or when we want to embed hypermedia. Also, we put “REST” logic into our database layer. It’s up to you to judge.

What about template languages? Let’s try jbuilder for JSON rendering.

Jbuilder.encode do |json|
  json.title  @lemon.title
  json.colors @lemon.colors
end

Nice! But, wait. How do I test this? Can I test this separately? What if I want different representations for the same model? Do I need different templates? And… is it cool to have format knowledge both in our parsing layer and in our rendering layer? I mean, both need to know about the title property and the colors array.

Representers: OOP to our Documents!

I won’t further discuss the shown concepts here. Let me just criticize that they are not object-oriented and encourage the distribution of document internals about the entire framework.

Here’s how representers can handle all that and make you a happy man at the same time!.

require 'roar/representer/json'
 
module FruitRepresenter
  include Roar::Representer::Base
 
  property :title
  collection :colors
end

This is all we need to declare the basic syntax of the fruit document. Note that it resides in a module which can be used anywhere in your app.

Rendering a Lemon

Now let’s say our database layer provides us a class Fruit with ActiveRecord-like behaviour.

lemon = Fruit.new(:title => "Lemon")
puts lemon.title #=> "Lemon"

Since the representer knows everything about the document format it can be used for rendering JSON. We just have to include the FruitRepresenter module into the class and new methods will be available.

Fruit.class_eval do # DB layer.
  include Roar::Representer::JSON
  include FruitRepresenter
end
 
lemon.to_json
#=> "{\"title\":\"Lemon\",\"colors\":[]}"

Awesome, the FruitRepresenter module gives us a #to_json method. Internally, this method compiles the JSON document by asking the represented object (aka lemon) for its properties and values. Remember, the representer knows about those properties, since we declared them. It does not know anything about ActiveRecord and the like.

Now, what about parsing?

Parsing a Lemon

The great thing about representers is: they work bidirectional. That alone is one of the main advantages to many other gems out there. Bidirectional? Let’s just see what that is.

orange = Fruit.from_json("{\"title\":\"Orange\"}")
puts orange.inspect
#=> #<Fruit:0x9df73a8 @title="Orange", @colors=[]>

We can parse representations and create objects from it! That’s bidirectional: rendering and parsing is combined in one representer.

Again, the representer does not know anything about the underlying database – it just creates an object it was mixed into, reads from the document and assigns properties using polite setters. Nothing more, bro.

Don’t like the class method? If you already have an instance, you can use #from_json on the instance.

orange.from_json("{\"title\":\"Yummy Orange\"}")
orange.title #=> "Yummy Orange"

Nesting Representers

Now that we have fruits, lets put ‘em in a bowl. A fruit bowl contains a list of fruits.

bowl = Bowl.new
bowl.items << lemon
bowl.items << orange

In order to bind the fruit bowl to a REST resource we write another representer module.

module BowlRepresenter
  include Roar::Representer::Base
 
  property :location
  collection :items, :as => Fruit
end
 
Bowl.class_eval do # DB layer.
  include Roar::Representer::JSON
  include BowlRepresenter
end

Properties can be typed using the :as option. The target class must be a representer, too. That’s the only requirement.

bowl.to_json
#=> {"items":[
  {"title":"Lemon","colors":[]},
  {"title":"Orange","colors":[]}
]}

Typed properties allow us to build more complex representations without breaking with OOP. The collection assignment makes building lists as easy as possible. And if you still need to tweak things, there are some helpful configuration options around – more on that in one of the next posts.

Representers love HATEOAS

HATEOAS? Check out this talk I gave if you want to learn about Hypermedia and HATEOAS.

Hypermedia helps clients to operate the API without having to compute URLs. We want hypermedia in our documents.

module BowlRepresenter
  include Roar::Representer::Feature::Hypermedia
 
  link :self do
    "http://bowls/#{location}"
  end
end

Including the Hypermedia feature dynamically adds a new method #link to our representer module. What does it do?

bowl.location = :desk
bowl.to_json
#=> {
"items":[
  {"title":"Lemon","colors":[]},
  {"title":"Orange","colors":[]}],
"links":[{"rel":"self","href":"http://bowls/desk"}]
}

Seems like an easy way to embed links in our documents. In roar-rails the Rails URL helpers work like a charm within the link blocks – making it super simple to provide hypermedia to consumers and still being railsy.

Representers on the Client Side

Ok, representers basically are plain modules. Why not use ‘em on the client side as well? The client doesn’t have access to the model layer – if it does, something’s wrong! However, it’s absolutely ok to share the representer modules.

class Bowl
  include Roar::Representer::JSON
  include Roar::Representer::Feature::HttpVerbs
  include BowlRepresenter # from a gem.
end

See how we simply use an empty class with the mixed-in representer on the client side? Remember, we don’t want to have access to the database here.

The next step is creating a new fruit bowl.

bowl = Bowl.new
bowl.location = "kitchen"
bowl.post!("http://bowls")

This code is enough to send a POST request to the specified URL. The bowl instance will serialize a JSON document, send it to the URL using the HttpVerbs feature, receive the new bowl, deserialize it and update its properties accordingly. You may know this behaviour from REST client gems like ActiveResource – here, with less code and manageable complexity.

Consume Hypermedia, it’s gooood.

The representer also makes it easy to extract hypermedia links from documents.

bowl.links[:self]
#=> "http://bowls/kitchen"

No parsing needed, the representer knows where to find your hypermedia. How cool is that?

XML is not a Crime!

Roar comes with both JSON and XML representers.

module BowlRepresenter
  include Roar::Representer::XML
end
 
bowl.to_xml
#=> '<bowl>
#  <link rel="self" href="http://bowl/kitchen"/>
#</bowl>'

Now choose if you want JSON or XML – it’s up to you! I still don’t understand the XML hating – did I miss something or is it just “too java”?

Roar – and more?

The Roar project is still evolving. However, the current API is almost stable. New features, new concepts, testing helpers, etc will be added over time just like in every framework. Roar is framework-agnostic and can be used anywhere, as long as it’s Ruby.

Its modulare feature architecture makes it easy to extend your documents. Currently, we have some exciting on-going brainstorming and hacking on features like client-side caching in the representer instance, generic error handling, validations, DSLs, … We need you to try it out, complain, propose, help, and spread the word. Thank you for reading until here, you rock!

Rails Misapprehensions: Query Parameters are RESTful

Tuesday, June 21st, 2011

We were discussing the design of search resources in a REST architecture after the REST talk at the EuRuKo. Usually, search resources process GET requests, compute a subset of searched items and return a representation of the respective items.

The following GET request illustrates this.

http://articles/search?type=shirt&color=red&size=s

It’s absolutely common to allow more parameters.

http://articles/search?type=shirt&color=red&size=s& \
  gender=female&limit=10&amount=20&

Where’s the search resource?

Now, let me state two facts about these URLs.

  • From a REST perspective, those two search queries refer to two different resources. Remember: Resources are addressed with unique URLs, and when URLs differ you’re addressing differing resources.
  • Within Rails, this doesn’t matter that much since both URLs are processed in the same controller. This is cool. A controller per definition is meant to expose a set of resources.

Long URLs and REST

After having discussed the meaning of resources the question that came up was

“Isn’t such a long URL with lots of query parameters comparable to clumsy XML-RPC arguments?”

Well, I’d say: No way.

  • Dynamic resources have to receive input in a certain manner – this makes them dynamic. Query parameters were designed to let users specify parameters. There’s nothing wrong with allowing input.
  • However, if you decide your URLs are getting too long you have to redesign your search resource architecture!

Exposing named queries

The REST cookbook – a fantastic write-up which I do strongly recommend – suggests to identify commonly used search criterias and expose those queries as separate resources.

Say we’re annoyed with the long “search red female shirts” URLs. Why not donate a dedicated resource?

http://articles/shirts/female?color=red&size=s

While this is just an example, it demonstrates how commonly used parameters were consolidated in a new URL base. Again, from the REST point-of-view, this points to a completely separate resource.

However, in Rails, this can simply be mapped to the search controller while providing the remaining parameters in the route definition.

match 'articles/shirts/female' => 'articles#search', 
  :defaults => { :gender => 'female',
                   :type => 'shirt' }

Controllers and Resources

Don’t give me a hard time about the routing – what I wanted to discuss is the way of thinking about resources: You’re free to map different URLs to one controller. One of main architectural concepts in REST is that it’s up to you how you design your resources and how to expose them.

Query parameters don’t kill your mother and choosing named URLs is free – it’s absolutey “RESTful”.

Representable gem released: Improve your REST representation code!

Monday, May 9th, 2011

The representable gem 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.

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.

<post>
  <id>1</id>
  <posted_at>2011-05-09</posted_at>
 
  <comment id="1">
    <text>This is stupid!</text>
  </comment>
  <comment id="3">
    <text>No, awesome post!</text>
  </comment>
</post>

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

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. Note that the <comment> 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.

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).

1
2
3
4
5
6
7
8
require 'representable/xml'
 
class Comment # < ...
  include Representable::XML
 
  representable_property :text
  representable_property :id, :from => "@id"
end

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

Nesting Representations

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

1
2
3
4
5
6
7
8
class Post # < ...
  include Representable::XML
 
  representable_property :id
  representable_property :posted_at
  representable_collection :comments, 
    :tag => :comment, :as => Comment
end

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

Rendering Documents

You want to render a document representing your post now.

Post.find(1).to_xml 
  # => "<post><id>1</id>comment id=\"1\"..."

Representable takes care of rendering. No magic included.

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
# => "[#<Comment:0x8545a08 @text=\"Your blog sucks.\">]"

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.

Other media types?

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

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

How does it help?

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.