HTTP REST Definition – Why REST API Does Not Follow the Facade Design Pattern

definitionhttprest

In comparing REST [api] structure with a OO model, I see these similarities:

Both:

  • Are data oriented

    • REST = Resources
    • OO = Objects
  • Surround operation around data

    • REST = surround VERBS (Get, Post, …) around resources
    • OO = promote operation around objects by encapsulation

However, good OO practices do not always stand on REST apis when trying to apply the facade pattern for instance:
in REST, you do not have 1 controller to handle all requests AND you do not hide internal object complexity.

Simple object relation between 2 concepts

Analogy between OO and REST

On the contrary, REST promotes resources publishing of all relations with a resource and other on at least two forms:

  1. via resource hierarchy relations (A contact of id 43 is composed of an address 453) : /api/contacts/43/addresses/453

  2. via links in a REST json response:

>> GET /api/contacts/43
<< HTTP Response {
   id: 43, ...
   addresses: [{
      id: 453, ...
   }],
   links: [{
      favoriteAddress: {
          id: 453
      }
   }]
}

Basic complexity hidden by objectA

Coming back to OO, the facade design pattern respect a Low Coupling between an objectA and its 'objectB client' and High Cohesion for this objectA and its internal object composition (objectC, objectD). With the objectA interface, this allow a developer to limit impact on objectB of the objectA internal changes (in objectC and objectD), as long as the objectA api (operations) are still respected.

In REST, the data (resource), the relations (links), and the behavior (verbs) are exploded in different elements and available to the web.

Playing with REST, I always have an impact on code changes between my client and server: Because I have High Coupling between my Backbone.js requests and Low Cohesion between resources.

I never figured out how to let my Backbone.js javascript application deal with "REST resources and features" discovery promoted by REST links. I understand that the WWW is meant to be served by multi servers, and that the OO elements had to be exploded to be serviced by many hosts in there, but for a simple scenario like "saving" a page showing a contact with its addresses, I end up with:

GET /api/contacts/43?embed=(addresses)
[save button pressed]
PUT /api/contacts/43
PUT /api/contacts/43/addresses/453

which lead me to move the saving action atomic transactional responsibility on the browsers applications (since two resources can be addressed separately).

With this in mind, if I cannot simplify my development (Facade design patterns not applicable), and if I bring more complexity to my client (handling transactional atomic save), where is the benefit of being RESTful ?

Best Answer

I think objects are only built correctly around coherent behaviors and not around data. I will provoke and say that data is almost irrelevant in the object oriented world. In fact, it's possible and sometime common to have objects that never return data, for example "log sinks", or objects that never return the data they are passed, for example if they calculate statistical properties.

Let us not confuse the PODS, (which are little more than structures), and the real objects that have behaviors (like the Contacts class in your example)1.

PODS are basically a convenience used to talk to repositories and business objects. They allow the code to be type safe. No more, no less. Business objects, on the other hand, provide concrete behaviors, like validating your data, or storing it, or using it to perform a calculation.

So, behaviors are what we use to measure "cohesion"2, and it's easy enough to see that in your object example there is some cohesion, even though you only show methods to manipulate top level contacts and no methods to manipulate addresses.

Regarding REST, you can see REST services as data repositories. The big difference with object oriented design is that there is (almost) only one design choice: you have four basic methods (more if you count HEAD, for example) and of course you have a lot of leeway with the URIs so you can do nifty stuff like pass many ids and get a larger structure back. Do not confuse the data they pass with the operations they perform. Cohesion and coupling are about code and not data.

Clearly, REST services have high cohesion (every way to interact with a resource is in the same place) and low coupling (every resource repository does not require knowledge of the others).

The basic fact remains, though, REST is essentially a single repository pattern for your data. This has consequences, because it's a paradigm built around easy accessibility over a slow medium, where there is a high cost for "chattiness": clients typically want to perform as few operations as possible, but at the same time only receive the data they need. This determines how deep an data tree you are going to send back.

In (correct) object oriented design, any non-trivial application will do much more complex operations, for example through composition. You could have methods for doing more specialized operations with the data -- which must be so, because while REST is an API protocol, OOD is used to build entire user facing applications! This is why measuring cohesion and coupling is fundamental in OOD, but almost insignificant in REST.

It should be obvious by now that analyzing data design with OO concepts is not a reliable way to measure it: it's like comparing apples and oranges!

In fact, it turns out that the benefits of being RESTful are (mostly) the ones outlined above: it's a good pattern for simple APIs over a slow medium. It is very cacheable, and shardable. It has fine grained control over chattiness, etc.

I hope this answers your (quite multifaceted) question :-)


1 This problem is part of a larger set of problems known as Object-Relational impedance mismatch. Proponents of ORMs are generally in the camp that explores the similarities between data analysis and behavior analysis, but ORMs have fallen under criticism of late because they seem not to really resolve the impedance mismatch and are considered leaky abstractions.

2 http://en.wikipedia.org/wiki/Cohesion_(computer_science)