NSimpleDB - Use Amazon´s SimpleDB data model in your applications now - Part 4
As explained in my previous postings, I implemented a local/embeddable version of the Amazon SimpleDB data model and API in C#. You can download the sources from my NSimpleDB Google Code Project and build the tuple space engine yourself, or you download the demo application which includes the engine as a single assembly: NSimpleDB.dll.
Using the SimpleDB API then can be as easy as referencing the engine assembly and opening a local tuple space file like this:
using NSimpleDB.Service.Contract;
ISimpleDBService ts;
ts = new NSimpleDB.Service.VistaDb.VistaDbSimpleDBService("hello.ts");
...
ts.Close();
See my previous posting for detailed examples.
Access to Amazon SimpleDB
The API I devised for the SimpleDB purposedly was quite "service oriented", although the implementation was just local. I did this so my implementation and Amazon´s eventually could be used interchangeably. Back then, though, I did not have access to SimpleDB due to the limited beta.
But that has changed in the meantime. I was able to use SimpleDB online and thus have now implemented access to it through the same ISimpleDBService interface. Just instanciate a different service implementation:
ts = new NSimpleDB.Service.Amazon.AmazonSimpleDBService("<accessKeyId>", "<secretAccessKey>");
Instead of the placeholders pass in your Amazon access key id and your secret access key and you´re done. From then on all operations through the interface will run on your online SimpleDB space.
Here´s a small example of what you could do: create a domain, store some items into that domain, query the items, retrieve the found items, delete the domain.
ts.CreateDomain("mydomain");
ts.PutAttributes("mydomain", "1",
new SimpleDBAttribute("name", "peter"),
new SimpleDBAttribute("city", "london"));
ts.PutAttributes("mydomain", "2",
new SimpleDBAttribute("name", "paul"),
new SimpleDBAttribute("city", "berlin"));
ts.PutAttributes("mydomain", "3",
new SimpleDBAttribute("name", "mary"),
new SimpleDBAttribute("city", "london"));
string nextToken = null;
string[] itemNames;
itemNames = ts.Query("mydomain", "['city'='london']", ref nextToken);
foreach (string itemName in itemNames)
{
Console.WriteLine("item: {0}", itemName);
ISimpleDBAttribute[] attributes;
attributes = ts.GetAttributes("mydomain", itemName);
foreach (ISimpleDBAttribute attr in attributes)
Console.WriteLine(" {0}={1}", attr.Name, attr.Value);
}
ts.DeleteDomain("mydomain");
(With regard to my previous API descriptions only a minor changes has occurred: you need to always pass in the nextToken as a ref parameter instead of an out parameter. But that´s a detail, I guess.)
This code runs locally as well as against SimpleDB online without change.
Under the hood I´m using Amazon´s own C# API for accessing SimpleDB. It was easy to program against - but I would not want to expose it as an API. For that I don´t find its usability too low. Too much meta data in the way of getting your problem solved.
Access to SimpleDB operation meta data
In order provide access to the meta data the Amazon SimpleDB API provides without compromising the simplicity of my ISimpleDBService interface, I decided to define a second interface: ISimpleDBDashboard.
Like a dashboard in your car this interface optionally "displays" what´s going on inside an ISimpleDBService implementation. AmazonSimpleDBService implements this interfaces and through it provides access to the response and exception meta data returned from the internally used Amazon API. To use it, just cast the service object like this:
ISimpleDBDashbord db = (ts as ISimpleDBDashbord);
There are only two properties on the dashboard interface: LastResponseMetaData and LastExceptionData. They give access to the meta data/exception data of the last operation issued on the current thread. So even in case you use the same service implementation on different threads, you always will be able to exactly see, what the status of the individual operations is. This is how I tried to avoid always returning some meta data object like Amazon does. It makes for a simpler API, I´d say. Call the dashboard properties right after any operation, if you like, e.g.
ts.DeleteDomain("mydomain");
Console.WriteLine("request id: {0}", db.LastResponseMetaData.RequestId);
Console.WriteLine("box usage: {0}", db.LastResponseMetaData.BoxUsage);
What´s next?
Well, that´s it for now. I have reached my initial goals of 1) provide a local version of the SimpleDB data model and API for all who want to play with it more easily than online, and 2) make the use the local tuple space and the real online SimpleDB equally possible and simple.
Of course I still have some ideas as to what can be improved (see the issue list online), but I now need to give the project a little rest. Please feel free, though, to use it and give me feedback on it via info [at] ralfw [dot] de, if you like.
Enjoy!