I’ve had a need to look at the APIs for DynamoDB and RDS database offerings by AWS and have been interested by how much they vary in terms of design. Whilst it’s true one (RDS) is an abstraction layer over two RDBMS and the other is a direct API to a single key-value NoSQL store, I think it’s more likely the distributed nature of the AWS development groups and relative ages of the two offerings that are most likely to have led to the differences. The RDS services have been around in the AWS stack since mid 2009 whilst DynamoDB was only add in late 2011.
(As a side note, I suspect the actual web service APIs provided by AWS are rarely used by many consumers: most people would interact with them indirectly via a native language binding in the form of the CLI or library, or via the AWS Management Console.)
At the highest level, the RDS API is XML-over-HTTP SOAP service using a WSDL to describe the contract. There are 34 separate actions that can be invoked against the service endpoint and all requests are issued via GET with parameters encoded as part of the query string. Not surprisingly, providing a single API over two quite different databases (MySQL and Oracle) causes some leaky abstractions at the parameter level of the API as can be seen with the differences in constraints in the CreateDBInstance service. Thankfully, once the instance has been created, these leaks are seldom visible in subsequent calls.
The RDS API does tip it’s hat slightly towards the REST-influenced world with its usage of HTTP status codes to provide some information about error conditions.
On the other hand, the far younger DynamoDB API takes a far more RESTful approach. No WSDL for DynamoDB and it’s JSON over HTTP instead of XML. Looks like a fuller embrace of HTTP code has been made for the error conditions but differentiating between client (4xx) and server (5xx) errors.
Beyond that things get a little weird as all requests are made via POST, irrespective of whether the operation is a create, read, update or delete. This is somewhat atypical of this type of API which often use the conventions in Step 2 of the Richardson Maturity Model.
Furthermore, all API actions (12 in total) must be encoded in the HTTP request header in the form of “x-amz-target: DynamoDB_20111205.CreateTable” which indicates this request will invoke the CreateTable action. Note here that the top level service (i.e., DynamoDB) and API version (i.e., 20111205) are included in this same header, which implies further APIs of a similar nature will be directed to the same endpoint. This is a contrary design to the SOAP APIs where a service-unique is used (e.g., https://rds.amazonaws.com/ for RDS)
At the time of writing, I cannot find any other native AWS APIs which use DynamoDB style of service, so it’s too early to tell whether this style is an outlier or whether it’s the standard that all future services will use. If it’s the latter, it will be interesting to see whether the design of the APIs will be further evolved towards more “mature” forms of RESTfulness via using the full set of common HTTP verbs rather than just POST. I would also much prefer to see endpoints of “http://api.dynamodb.amazonaws.com” and the introduction of some notion of resources (i.e., the R in REST) via the urls in the form of “http://api.dynamodb.amazonaws.com/table”.