Accessing Azure Tables and Blobs via REST

In a previous post, I implemented a few of the Azure Table REST APIs as a starting point for testing without having to use the Storage Client sample that ships in the Azure SDK. The Azure Storage REST API is documented here. Instructions and the updated code are at the bottom of this post.

Version 2

In this version of the code, I added support forall of the Azure Table REST API as well as the Azure Blob API (minus the blob chunking). Based on the docs, the queue API looks very similar to the Blob API, so it shouldn't be difficult to implement.

For the entity insert and update table methods, I chose to use a simple entity class and use reflection to convert the properties into the appropriate XML payload. I liked this better than using a dictionary type collection or hard coding the implementation.

My original goal was to have all of the REST functionality encapsulated in the RESTHelper class. After trying that for a while, I decided that there were enough differences to warrant different implementations for blobs and tables. The account, secret, SharedKey generation, and exception handling are shared, but the signature creation and request execution are separate implementations.

To make the logic a little simpler, I implemented a “command” parameter in the Blob RESTExec method. For most requests, this is the HTTP Method, but for some requests additional headers have to be added. This seems simpler than using a combination of URI and Method or adding another parameter. There is code that uses the Command parameter to modify the URI, set the HTTP method, and add headers as appropriate.

Caveats

· The code still only works on Azure Storage, it does not work on development storage (see my reasoning in the previous post).

· I have only implemented / tested with string data.

· The updated code is sample code quality with limited error handling, testing, and comments, so it’s only appropriate for experimentation and as a starting point.

· The code is still all in one file, which is easy to post and get running the first time, but not a best practice for a real app.

· You still need to update the account / secret information in the RESTHelper class.

Feedback

One of the Azure developers clarified a comment I made in my original post about including query strings in the signature. In his words: “For blobs, one must include only the ‘comp’ query parameter if it exists, not the entire query string. The ‘comp’ query parameter identifies a sub-resource and hence is integral to the resource being operated on by the request. This is the reason to include it in the signature. Table storage doesn’t use the ‘comp’ query parameter, so we don’t include it there. This can be simply said as “Include the ‘comp’ query parameter into the canonicalized resources if it exists.” This probably holds good for all services.” This makes sense and helped me when I was implementing the Blob API. Thanks Rags!

Another suggestion was to use the .NET ATOM classes to process the Table results. I tried this, but chose to stick with direct XML instead. If you choose to use the Table REST API directly, you might want to look into the syndication classes.

Learnings

· Make sure to wrap all of your web calls with using or explicitly close the connections.

· Azure Blob containers don’t appear to support capital letters.

· Getting the signature exactly right is still the hardest part.

o I now understand why the API forces resources and headers to be canonicalized.

· The REST API is great for viewing arbitrary tables without knowing the structure in advance.

Using the Sample Code

Create a new console application named AzureStorageConsole, then replace the code in Program.cs with the code attached below.

Change the “accountN” and “secretN” references to your Azure credentials. I decided to embed the storage account information in the code vs. reading it from a config file. This implementation uses a helper class to allow you to specify the account in the constructor, which makes it easy to use different accounts simultaneously.

Note that you do not have to install the Azure SDK to use the sample code. A vanilla install of .NET 3.5 will work.

Program.cs