How to: Use Azure DocumentDB with Azure Mobile Services

With the release of DocumentDB, developers now have access to a scalable, nimble, and robust NoSQL platform as a service in Azure. I thought it would be a good idea to showcase how you can use DocumentDB with Azure Mobile Services. But before we dive into the details, and with the goal of providing some insights into how I implemented this integration, let’s discuss some aspects of the design of Azure Mobile Services with a .NET back end.

 

Note: This integration could be beneficial if you want to use some features of Azure Mobile Services, such as authentication, notifications, etc., while benefiting from a NoSQL database approach.

To get started, let’s cover some of the basics of Azure Mobile Services. First, it is important to notice that Azure Mobile Services with a .NET back end is built using the WebAPI, so controllers, models, routes, etc., are also the building blocks of the service. Another design consideration is that Azure Mobile Services separates the operations of the API and the mechanism that handles how the data is stored. Because of this separation of concerns, you can change where data comes from or where it is saved, without major changes to the implementation of the APIs. To achieve this, the design of Azure Mobile Services introduces the concept of a domain manager.

The role of the domain manager is to manage the semantics of the underlying repository of data and provide a consistent interface that allows the typical create, read, update, and delete (CRUD) scenarios.  On top of the domain manager, Azure Mobile Services provides a generic controller that exposes this functionality as REST operations. The controller also has a type parameter and is the type of entity representing the data that the client receives and sends to the API. This entity is often referred as a data transfer object (DTO). In the simplest case, the DTO reflects the underlying data model.

 

image

Note: There are scenarios in which you will want to use an existing database where it is necessary to expose a subset or a variation of data via the API. In such cases, there is another set of objects that represents the data model, and creating a DTO mapping process of some sort is necessary. The implementation of Azure Mobile Services includes a convenient mapper component (Automap), as well as a mapping domain manager to facilitate these tasks.

Now let’s discuss DocumentDB. Simply put, you can think of DocumentDB as a JSON repository where each element (resource) is addressable via a URI. At the top is your account followed by a set of databases. Each database can have one or more collections of documents. A document is a main data unit, and in the context of Azure Mobile Services, entities are documents. To reflect this I will use the term “document entity” going forward.

 

Note: You can create a new DocumentDB service instance through the preview portal only.

 

image

Following the design considerations discussed, we will create a domain manager that abstracts the nuances of persisting and retrieving documents from the DocumentDB instance and a controller that leverages it. So let’s get to it!

Document Domain Manager

For the implementation of the domain manager for DocumentDB, we will implement the methods shown in the diagram below, and to do this we will leverage the DocumentDB .NET SDK.

image

The methods are basically the same as those used for the interface IDomainManager<T>. Notice that we are not explicitly implementing this interface due to the constraint that makes instances of <T> implement the ITableData interface. ITableData defines basic properties that are not applicable for a document stored in DocumentDB.

You can check the full implementation here.

 

Note: This full implementation assumes that you have two settings in your config file: endpoint and authKey. You can get the values for these settings in the Azure portal.

The Controller


Next, we will need to implement a base (abstract) controller that expects the domain manager we just discussed. In addition, we need to define a base type for our document entities. The DocumentDB client has a handy class called Resource, which has some basic properties that reflect key metadata of a document entity as well as an ID property. So let’s require that all document entities derive from this class by placing a constraint in our controller.


The following figure shows the constraint and the methods we will need to implement. You can check the complete implementation here.

image

Playing with DocumentDB

So now we have everything we need to define a new entity and then easily implement an API that exposes the CRUD operations having DocumentDB as the back end.
Let’s create a Todo item entity.

public class DocumentTodoItem:Resource
{

[JsonProperty(PropertyName = "name")]
public string Name { get; set; }

[JsonProperty(PropertyName = "desc")]
public string Description { get; set; }

[JsonProperty(PropertyName = "isComplete")]
public bool Completed { get; set; }
}


And a controller derived from our base controller class.

 

public class TodoItemDocumentController:DocumentController<DocumentTodoItem>
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
DomainManager = new DocumentEntityDomainManager<DocumentTodoItem>("AMSDocumentDB", "todolist", Request, Services);
}

public IQueryable<DocumentTodoItem> GetAllTodoItems()
{
return Query();
}

public SingleResult<DocumentTodoItem> GetTodoItem(string id)
{
return Lookup(id);
}

public Task<DocumentTodoItem> ReplaceTodoItem(string id, DocumentTodoItem item)
{
return ReplaceAsync(id, item);
}

public async Task<IHttpActionResult> PostTodoItem(DocumentTodoItem item)
{
var doc = await InsertAsync(item);

return CreatedAtRoute("DefaultApis", new { id = doc.Id }, doc);
}

public Task DeleteTodoItem(string id)
{
return DeleteAsync(id);
}
}


Let’s run it locally and create a Todo item.

image


Let’s check DocumentDB using Document Explorer via the portal—and voila!


image

 

Conclusion


In today’s blog post, I showed you how you can use DocumentDB as the back end for Azure Mobile Services. You can find the complete example here.


5 Comments

  • Great article. Question: Is it necessary to have the override in the Initialize of TodoItemDocumentController? What is it overriding as I don't see an Initialize in your base?

  •       Commented

    Thank you Jesus! Question: When you follow up the POST in your example with a GET using the same api screen do you see the "isComplete" value? I'm noticing that the bool value is not showing up even though fiddler shows that it is returned with the json. The returned json value is 'False' instead of 'false'. I'm not sure why that case switch is happening but I'm thinking that the case ('False') might be messing up the mapping but I'm not sure where to intercept and verify that. Any help is appreciated. Thanks

  • For anyone else that might be following this great post, be aware that if you try POSTing to the controller with a HTTP instead of HTTPS, you may not see any errors, but the controller will silently roll over to a GetAllTodoItems and return a 200 instead of a 201.

    The fooler is that the POST works locally either way but when you try to host it on Azure Mobile App (not Mobile Services) and use Postman or whatever, HTTP just doesn't work.

    Took me a minute on that one.

    HTH

Post Reply