Amazon Web Services: about REST API, Query API, SOAP API and possible inconsistencies

In this blog post I dedicate myself to the definitions and differences of SOAP, Query and REST API you can use to manage Amazon Web Services. While digging into the topic, some confusion and questions came up, both of which I could clarify by reading a good book. It turns out that Amazon does not use consistent API terms and I would like to share this information.

You perhaps know Amazon Web Services (AWS). If not: hurry up: it’s Infrastructure-as-a-Service-cloud-computing at its finest :-) . AWS consists of real web services: they all are controlled over HTTP with various types of abstraction — the different Application Programming Interfaces (APIs): Some services can be controlled via the “REST API”, some via the “Query API”, some via the “SOAP API” and even the term “REST-Query API” appears. The following table gives an overview of the services and the corresponding available APIs, as stated by AWS (taken out of the documentation by summer 2009):

Service REST Query SOAP REST-Query
S3 X X
EC2 (incl. sub services) X X
SQS X X
SimpleDB X X
FPS X X
CloudFront X
Elastic MapReduce X
Fulfillment Web Service X X
Mechanical Turk X X
DevPay X X

The red fields indicate that I think there something is wrong. Read on to learn why.

At first, I was a bit confused about the different API types. In particular, it was not clear to me why we have to distinguish REST and Query API. In both cases the requests to AWS are based on standard HTTP protocol requests like GET and POST. REST and Query API do not use a protocol on top of HTTP, in contrast to the SOAP API: it relies on XML documents transported via HTTP.

Additionally, it was not clear to me why we have to have at least three different API types. Is that necessary? What are pros and cons?

If you look around for client libraries providing the AWS API for famous programming languages like Python, Java, Ruby and so on, you mostly find libraries implementing the REST and Query API. SOAP API — which is available for the majority of the services — is implemented quite seldom. This confused me.

Although the cooperative guys contributing to the boto mainling list already helped me with this topic, I looked for a book to read about this field in more detail. In Programming Amazon Web Services by James Murty, I found a very good summary about the topic and — with that — answers to my questions. I will now quote big parts, because I think that it could be very useful to some people out there:

Interfaces: REST and Query Versus SOAP

AWS infrastructure services are made available through three separate APIs: REST, Query, and SOAP. In this book we will focus only on the REST and Query APIs and will not demonstrate how to use the SOAP APIs. We have a number of reasons for doing this, reasons which will become clearer after a brief explanation of the differences between the interfaces.

REST interfaces

The REST interfaces offered by AWS use only the standard components of HTTP request messages to represent the API action that is being performed. These components include:

  • HTTP method: describes the action the request will perform
  • Universal Resource Identifier (URI): path and query elements that indicate the resource on which the action will be performed
  • Request Headers: pieces of metadata that provide more information about the request itself or the requester
  • Request Body: the data on which the service will perform an action

Web services that use these components to describe operations are often termed RESTful services, a categorization for services that use the HTTP protocol as it was originally intended.

Query interfaces

The Query interfaces offered by AWS also use the standard components of the HTTP protocol to represent API actions; however these interfaces use them in a different way. Query requests rely on parameters, simple name and value pairs, to express both the action the service will perform and the data the action will be performed on. When you are using a Query interface, the HTTP envelope serves merely as a way of delivering these parameters to the service.

To perform an operation with a Query interface, you can express the parameters in the URI of a GET request, or in the body of a POST request. The method component of the HTTP request merely indicates where in the message the parameters are expressed, while the URI may or may not indicate a resource to act upon.

These characteristics mean that the Query interfaces cannot be considered properly RESTful because they do not use the HTTP message components to fully describe API operations. Instead, the Query interfaces can be considered REST-like, because although they do things differently, they still only use standard HTTP message components to perform operations.

SOAP interfaces

The SOAP interfaces offered by AWS use XML documents to express the action that will be performed and the data that will be acted upon. These SOAP XML documents are constructed as another layer on top of the underlying HTTP request, such that all the information about the operation is moved out of the HTTP message and encapsulated in the SOAP message instead.

[…]

The approach used in the SOAP interfaces are very different from those used by the REST and Query interfaces. Operations expressed in SOAP messages are completely divorced from the underlying HTTP message used to transmit the request, and the HTTP message components, such as method and URI, reveal nothing about the operation being performed.

The main reason we eschew the SOAP interface in this book is because we believe that SOAP interfaces in general add unnecessary complexity and overhead, effectively spoiling the simplicity and transparency that can make web services such powerful and flexible tools. […] We are not alone in feeling this way. According to Amazon staff members, a vast majority of developers use the REST-based APIs to interact with AWS.

Thank you, James Murty for providing a deeper understanding. With this knowledge, I looked through the developer guides of the different services to check if everything just learned really fits to the actual API realizations and their terms (given by AWS). I found some inconsistencies:

Amazon’s DevPay service: two names for the same thing

As you can read here, this service is managed via SOAP API or “REST-Query” API. “REST-Query API” characterizes exactly the same method of invoking requests as the “Query API” anywhere else within AWS, as stated in the DevPay documentation: “REST-Query requests are simple HTTPS requests, using the GET or POST method with query parameters in the URL”.

An example REST-Query API request for DevPay:

https://ls.amazonaws.com/?Action=ActivateHostedProduct​&ActivationKey=XX​&ProductToken=XX&AWSAccessKeyId=XX&Version=XX&Timestamp=XX​&Signature=XYZ

For comparison, an example Query API request for EC2:

https://ec2.amazonaws.com/?Action=DescribeImages&ImageId.1=XX&Version=XX&Expires=XX&Signature=XX&SignatureVersion=XX&SignatureMethod=XX&AWSAccessKeyId=XX

Hence, this method should simply get called “Query API”, too.

Amazon’s Mechanical Turk service: it’s not RESTful

This service can be controlled via SOAP or REST API — says Amazon. But when we look at the description of this “REST API”, it’s doubtable that “REST API” is the right term here: “REST requests are simple HTTP requests, using either the GET method with parameters in the URL, or the POST method with parameters in the POST body”

Let’s look at an example request of this Mechanical Turk “REST API”:

http://mechanicalturk.amazonaws.com/?Service=AWSMechanicalTurkRequester&AWSAccessKeyId=XX&Version=XX&Operation=XX&Signature=XX&Timestamp=XX&ResponseGroup.0=XX&ResponseGroup.1=XX

There is almost no difference to the EC2 Query API request example above: It’s just a GET request and a bunch of parameters. From my perspective, the URI does not represent the resource on which the action will be performed, although ?Service=AWSMechanicalTurkRequester possibly looks a bit like that. But all the parameters afterwards argue against calling this API RESTful. Hence, this API should have been called Query API, too.

In conclusion, for DevPay and Mechanical Turk the corrections in the table from above should look like this:

Service REST Query SOAP REST-Query
Mechanical Turk X (wrong) X X
DevPay X X X (wrong)

What do you think? I did not read Fielding’s thesis, so maybe I’ve still too little knowledge here.

2 Pingbacks/Trackbacks