Joined April 2012
·

dotnetCarpenter

Front-end developer since '007'.replace(/(\d{3})/, '2$1') at Napp
·
Sweden
·
·
·

Posted to FuckYourCode over 1 year ago

Further resources

I often use this diagram from Ruby's Webmachine when deciding the correct path for REST responses.

I find this article, about modeling RESTful representations in JavaScript, food for thought, as a concrete example of REST data exchange.

About Versions

I want to add a citation from Howard Dierkings article Versioning RESTful Services.

If I did a lot of this sort of resource versioning, it is very possible that I could end up with an ugly-looking URL space. But REST was never about pretty URLs and <strong>the whole point of the hypermedia constraint is that clients should not need to know how to construct those URLs in the first place</strong> – so it really doesn’t matter whether they’re pretty or ugly – to your client, they’re just strings.
So to summarize

This post ended up being longer than I had planned, so here’s the summary.

In REST, the contract between clients and services is the uniform interface
How you version depends on what part of the uniform interface you’re changing

If you’re adding only, go ahead and just add it to the representation. Your clients should ignore what they don’t understand

If you’re making a breaking change to the representation, version the representation and use content negotiation to serve the right representation version to clients

If you’re changing the meaning of the resource by changing the types of entities it maps to, version the resource identifier (e.g. URL)

While a little light on how <cite>Versioning a representation over an existing media type will look</cite> like, I tend to agree on his assessment.

I call the field uri in the example below. In the original REST text it's called source link.

{
  "list": [
    {
      "name": "ACME Books",
      "type": "list",
      "uri": "http://acme.com/books/"
    },
    {
      "name": "My book #1 - ACME Books",
      "type": "product",
      "uri": "http://acme.com/books/mybook/1"
    },
    {
      "name": "ACME Toys",
      "type": "list",
      "uri": "http://acme.com/toys/"
    }
  ]
}

The list is pretty straightforward. name could be displayed, type give us a way to add different visual representation of the resource and the uri is the source link to the resource. An implementation of the client, using Handlebars, could be:

<script id="acme-list" type="text/x-handlebars-template">
  {{#each list}}
  <h2><a href="{{uri}}">{{name}}</a></h2>
  <div class="acme-element-{{type}}">Lorem ipsum</div>
  {{/each}}
</script>

note that this implementation will leak memory and has other issues as well

// any REST client MUST have at least one known
// endpoint to the server
var RESTendpoint = "http://acme.com/";
display( html( JSON.parse( getData(RESTendpoint ) ) ) );
function html(data) {
  var source   = document.getElementById("acme-list").innerHTML;
  var template = Handlebars.compile(source);
  var html = template(data);
  [].forEach.call(html.getElementByTagsName("a"), applyClickEvent);
  return html;
}
function applyClickEvent(a) {
  a.addEventListener("click", function() {
    display( html( JSON.parse( getData(this.href) ) ) );
  }, false);
}
function getData(uri) {
  // do a request based on the uri
  return data;
}
function display(html) {
  document.appendChild(html);
}

The above, simple implementation has no restrictions to how deep it can follow a data diagram/graph on the server. There is actually no logic that tells the code to stop at any point. If you add another layer (e.g. in the database on the server) the client will happily render this new layer too. This is just pseudo code, so don't despair if you can't get it to work.

I think you missed out on an important REST principle. The API SHOULD communicate endpoint(s) to deeper level resources. Imagine a list of categories, where sub categories exists. By reserving a field for "next level" resource, the data or server can alter or introduce new levels with zero change to the client code. Such a field MUST be in the format of a hyper link. Like all other REST endpoints.
I can dig up the standard text if you like?

Achievements
130 Karma
1,220 Total ProTip Views