View on GitHub

swisspush

Community Contributions by Developers in the Swiss Postal IT

14 July 2015 - Laurent Bovet

rest-edit browser

Introduction

There is something I like in REST APIs: the URIs. Although, HATEOAS tend to make them invisible, or not important, I find their structuring power very interesting.

For decades and decades, we structure information in a hierarchical way. This is probably the most natural structure in our computer-biased brains. Filesystems show the same tree structure since… the year they were born.

Today, we are in the REST API era. The current movement tries to capture the best of the browser-navigated web and apply it to the software integration world. Structured URIs are certainly one of the good parts to take over.

We discuss here reasons to use hierarchical structure in REST APis and tools that are good for that.

Flat vs. Hierarchical

Flat

We can design “flat” APIs, i.e. where URIs do not go deeper that one level:

GET /blogs/swisspush/articles

{
  "articles": [
    "4972057",
    "6274382"
   ]
}

GET /articles/4972057

{
   "subject": "Hierarchical RESTful Storage",
   "author": "Laurent Bovet"
}

This has two consequences:

  • Article ids must be unique across all blogs.
  • An article can belong to more than one blog.

Hierarchical

In this case, it would be more natural to model the blog-article relationship in a hierarchical way:

GET /blogs/swisspush/articles

{
  "articles": [
    "1",
    "2"
   ]
}

GET /blogs/swisspush/articles/1

{
   "subject": "Hierarchical RESTful Storage",
   "author": "Laurent Bovet"
}

In UML, we would name that an aggregation. The aggregation semantics are naturally true. For instance, we expect that:

DELETE /blogs/swisspush

will also delete all its blog articles and let no orphan.

Generic API

In the example example above, we see that the tree structure is very similar to one of a filesystem, which is a generic storage solution.

So, we can design a generic REST service that implements CRUD operations (GET, PUT, DELETE) with which we can realize our blog API.

Let’s create a new blog with two articles:

PUT /blogs/wleaks/articles/1

{
   "subject": "US tap EU lines",
   "author": "Julienne Essenge"
}

PUT /blogs/wleaks/articles/2

{
   "subject": "EU to tap US lines",
   "author": "Anonymous"
}

Note: Intermediate “folders” are automatically created.

GET /blogs/wleaks/articles

{
  "articles": [
    "1",
    "2"
   ]
}

Software

REST Storage

Given that a lot of our APIs just gives access to data and can be modelled in hierarchies like the one above, we wrote a generic storage software: vertx-rest-storage.

It is realized as a Vert.x module, so it can be easily integrated in a non-blocking Vert.x application but also in any Java application, thank Vert.x embeddable platform.

As it is backed by Redis, it is very performant. Alternatively, it can be backed by a filesystem.

Developer Tools

This REST storage has proven very useful in many cases. Not only as a generic backend for storing data and give direct REST access to them but also to mock APIs that are not yet implemented.

As we use it everyday in all our development phases, it gained developer convenience with rest-edit, an HTML/JS UI for manipulating resources in the storage.

Based on Ace, it makes developer life very easy when authoring JSON (and others) directly in the browser.

rest-edit browser

Give it a Try

You can clone and build from GitHub or simply try this Docker Image bundling the storage and developer tools.

docker run quay.io/lbovet/rest-storage-bundle

Open http://localhost:8989/tools/browser.html

This image is meant as a demo only. It stores resources in the container filesystem.

Resource Expiration

In many use cases, we use REST storage as an intermediate between backends generating data and clients consuming this data. Very often, the data has a limited validity and does not make sense after some time.

So, REST storage supports a header defining the time-to-live of resources. (Note: available only in the Redis version).

PUT /notifications/alert1
X-Expire-After: 600
{
   "message": "Please call me asap"
}

This resource will automatically disappear from the collection after 10 minutes.

Conclusion

Hierarchical models satisfy us in 80% of cases. We increased dramatically development efficiency in all this cases.

From prototyping to integration tests, it brings its value all along the development chain. Non-developers got trained to REST thank the convenience tools.


blog comments powered by Disqus