, , , , ,

Following on from a previous post on AWS APIs, I made a comment about the Dynamo DB and to what degree it’s achieved RESTful nirvana according to the Richardson Maturity Model (RMM).  Now whether or not fully Level 3 maturity is appropriate or even desirable in all cases is a topic for another conversation, but I thought I’d look at how the API might differ if it was as RESTful as can be…

Level 1 – Resources

So what are the resources represented by DynamoDB?  Well looking at the 12 operations in the API documentation, I can see::

  • DATABASE, from which we can batch get
  • TABLE, which we can; create, delete, list, query, scan and update
  • Table METADATA, which we can describe (note: I originally included this as just another attribute of table rather than a separate request)
  • Table ITEM, which we can put, delete, update and get

Level 2 – HTTP Verbs

So with this knowledge, we can apply the default semantics of the common HTTP verbs, to get:

  • GET /tables (list)
  • POST /tables (create)
  • GET /tables/<name>/<primary-key-hash> (query)
  • GET /tables/<name> (scan)
  • PUT /tables/<name> (update)
  • DELETE /tables/<name> (delete)
  • GET /tables/<name>/metadata (describe)
  • GET /tables/<name>/item/<primary-key-hash> (get)
  • DELETE /tables/<name>/item/<primary-key-hash> (delete)
  • PUT /tables/<name>/item/<primary-key-hash> (update)
  • POST /tables/<name>/item (put)
  • GET /database (batch get)

Not entirely sure about this last one. The request parameters are for a multi-table, multi-attribute query for items but the wide scope of this query put it at a level about a single table.

Note that I’ve used the PUT and DELETE verbs which are not in common use in the browser world, but have been part of the HTTP standard since forever and are the most “correct” verbs to use given the semantics required.

Level 3 – HATEOAS

Moving onto Level 3 and the world of HATEOAS to assist in API discoverability, we now need to look into the specifics of the responses to certain API calls to chain together the logical links of relationships between the different sections of the API.

The ideas behind HATEOAS suggest that if you CREATE a TABLE, the response should tell you how to DESCRIBE, LIST, UPDATE and DELETE the table.  If you SCAN an existing TABLE, the response should tell you how to DESCRIBE, UPDATE and DELETE the table and so on.  Likewise, if you PUT a new item into a TABLE, then the response should tell you how to GET, DELETE and UPDATE that same item.

It only takes a single example to show how the HATEOAS stuff could work in the wild – I’ll take a possible response to SCANning a TABLE and cherry pick some aspects from the draft JSON Schema work to add in the hypermedia links back to the API.


GET /tables/foobar HTTP/1.1


HTTP/1.1 200
x-amzn-RequestId: 8966d095-71e9-11e0-a498-71d736f27375
content-type: application/x-amz-json-1.0
content-length: ...

"links" : [
    {"href" : "/tables/foobar",
    "rel" : "self"},
    {"href" : "/tables/foobar/metadata",
     "rel" : "describe"},
    {"href" : "/tables/foobar",
     "rel" : "delete"},
    {"href" : "/tables/foobar",
     "rel" : "update"}

It’s been an interesting thought exercise to re-examine the DynamoDB API from the RMM perspective.  I’ve focussed on the resources, verbs and HATEOAS aspects, but haven’t really looked into what HTTP status codes (201, 500, etc) are appropriate for the various response conditions applicable to each API call.  I’ve shown how the API could look in light of the RMM.  Like many public RESTful APIs, the DynamoDB one falls well short of Level 3 maturity.  Do AWS see this as being a shortcoming in the design of the API?  Time will tell.  Personally, the effort required to build a Level 2 API from where they are now is minimal, embracing HATEOAS is a step further both in terms of thinking and implementation effort.