Consume an Azure Cosmos DB Document Database in Xamarin.Forms
An Azure Cosmos DB document database is a NoSQL database that provides low latency access to JSON documents, offering a fast, highly available, scalable database service for applications that require seamless scale and global replication. This article explains how to use the Azure Cosmos DB .NET Standard client library to integrate an Azure Cosmos DB document database into a Xamarin.Forms application.
Microsoft Azure Cosmos DB video
An Azure Cosmos DB document database account can be provisioned using an Azure subscription. Each database account can have zero or more databases. A document database in Azure Cosmos DB is a logical container for document collections and users.
An Azure Cosmos DB document database may contain zero or more document collections. Each document collection can have a different performance level, allowing more throughput to be specified for frequently accessed collections, and less throughput for infrequently accessed collections.
Each document collection consists of zero or more JSON documents. Documents in a collection are schema-free, and so do not need to share the same structure or fields. As documents are added to a document collection, Azure Cosmos DB automatically indexes them and they become available to be queried.
For development purposes, a document database can also be consumed through an emulator. Using the emulator, applications can be developed and tested locally, without creating an Azure subscription or incurring any costs. For more information about the emulator, see Developing locally with the Azure Cosmos DB Emulator.
This article, and accompanying sample application, demonstrates a Todo list application where the tasks are stored in an Azure Cosmos DB document database. For more information about the sample application, see Understanding the sample.
For more information about Azure Cosmos DB, see the Azure Cosmos DB Documentation.
Note
If you don't have an Azure subscription, create a free account before you begin.
Setup
The process for integrating an Azure Cosmos DB document database into a Xamarin.Forms application is as follows:
- Create an Azure Cosmos DB account. For more information, see Create an Azure Cosmos DB account.
- Add the Azure Cosmos DB .NET Standard client library NuGet package to the platform projects in the Xamarin.Forms solution.
- Add
using
directives for theMicrosoft.Azure.Documents
,Microsoft.Azure.Documents.Client
, andMicrosoft.Azure.Documents.Linq
namespaces to classes that will access the Azure Cosmos DB account.
After performing these steps, the Azure Cosmos DB .NET Standard client library can be used to configure and execute requests against the document database.
Note
The Azure Cosmos DB .NET Standard client library can only be installed into platform projects, and not into a Portable Class Library (PCL) project. Therefore, the sample application is a Shared Access Project (SAP) to avoid code duplication. However, the DependencyService
class can be used in a PCL project to invoke Azure Cosmos DB .NET Standard client library code contained in platform-specific projects.
Consuming the Azure Cosmos DB account
The DocumentClient
type encapsulates the endpoint, credentials, and connection policy used to access the Azure Cosmos DB account, and is used to configure and execute requests against the account. The following code example demonstrates how to create an instance of this class:
DocumentClient client = new DocumentClient(new Uri(Constants.EndpointUri), Constants.PrimaryKey);
The Azure Cosmos DB Uri and primary key must be provided to the DocumentClient
constructor. These can be obtained from the Azure Portal. For more information, see Connect to an Azure Cosmos DB account.
Creating a Database
A document database is a logical container for document collections and users, and can be created in the Azure Portal, or programmatically using the DocumentClient.CreateDatabaseIfNotExistsAsync
method:
public async Task CreateDatabase(string databaseName)
{
...
await client.CreateDatabaseIfNotExistsAsync(new Database
{
Id = databaseName
});
...
}
The CreateDatabaseIfNotExistsAsync
method specifies a Database
object as an argument, with the Database
object specifying the database name as its Id
property. The CreateDatabaseIfNotExistsAsync
method creates the database if it doesn't exist, or returns the database if it already exists. However, the sample application ignores any data returned by the CreateDatabaseIfNotExistsAsync
method.
Note
The CreateDatabaseIfNotExistsAsync
method returns a Task<ResourceResponse<Database>>
object, and the status code of the response can be checked to determine whether a database was created, or an existing database was returned.
Creating a Document Collection
A document collection is a container for JSON documents, and can be created in the Azure Portal, or programmatically using the DocumentClient.CreateDocumentCollectionIfNotExistsAsync
method:
public async Task CreateDocumentCollection(string databaseName, string collectionName)
{
...
// Create collection with 400 RU/s
await client.CreateDocumentCollectionIfNotExistsAsync(
UriFactory.CreateDatabaseUri(databaseName),
new DocumentCollection
{
Id = collectionName
},
new RequestOptions
{
OfferThroughput = 400
});
...
}
The CreateDocumentCollectionIfNotExistsAsync
method requires two compulsory arguments – a database name specified as a Uri
, and a DocumentCollection
object. The DocumentCollection
object represents a document collection whose name is specified with the Id
property. The CreateDocumentCollectionIfNotExistsAsync
method creates the document collection if it doesn't exist, or returns the document collection if it already exists. However, the sample application ignores any data returned by the CreateDocumentCollectionIfNotExistsAsync
method.
Note
The CreateDocumentCollectionIfNotExistsAsync
method returns a Task<ResourceResponse<DocumentCollection>>
object, and the status code of the response can be checked to determine whether a document collection was created, or an existing document collection was returned.
Optionally, the CreateDocumentCollectionIfNotExistsAsync
method can also specify a RequestOptions
object, which encapsulates options that can be specified for requests issued to the Azure Cosmos DB account. The RequestOptions.OfferThroughput
property is used to define the performance level of the document collection, and in the sample application, is set to 400 request units per second. This value should be increased or decreased depending on whether the collection will be frequently or infrequently accessed.
Important
Note that the CreateDocumentCollectionIfNotExistsAsync
method will create a new collection with a reserved throughput, which has pricing implications.
Retrieving Document Collection Documents
The contents of a document collection can be retrieved by creating and executing a document query. A document query is created with the DocumentClient.CreateDocumentQuery
method:
public async Task<List<TodoItem>> GetTodoItemsAsync()
{
...
var query = client.CreateDocumentQuery<TodoItem>(collectionLink)
.AsDocumentQuery();
while (query.HasMoreResults)
{
Items.AddRange(await query.ExecuteNextAsync<TodoItem>());
}
...
}
This query asynchronously retrieves all the documents from the specified collection, and places the documents in a List<TodoItem>
collection for display.
The CreateDocumentQuery<T>
method specifies a Uri
argument that represents the collection that should be queried for documents. In this example, the collectionLink
variable is a class-level field that specifies the Uri
that represents the document collection to retrieve documents from:
Uri collectionLink = UriFactory.CreateDocumentCollectionUri(Constants.DatabaseName, Constants.CollectionName);
The CreateDocumentQuery<T>
method creates a query that is executed synchronously, and returns an IQueryable<T>
object. However, the AsDocumentQuery
method converts the IQueryable<T>
object to an IDocumentQuery<T>
object which can be executed asynchronously. The asynchronous query is executed with the IDocumentQuery<T>.ExecuteNextAsync
method, which retrieves the next page of results from the document database, with the IDocumentQuery<T>.HasMoreResults
property indicating whether there are additional results to be returned from the query.
Documents can be filtered server side by including a Where
clause in the query, which applies a filtering predicate to the query against the document collection:
var query = client.CreateDocumentQuery<TodoItem>(collectionLink)
.Where(f => f.Done != true)
.AsDocumentQuery();
This query retrieves all documents from the collection whose Done
property is equal to false
.
Inserting a Document into a Document Collection
Documents are user defined JSON content, and can be inserted into a document collection with the DocumentClient.CreateDocumentAsync
method:
public async Task SaveTodoItemAsync(TodoItem item, bool isNewItem = false)
{
...
await client.CreateDocumentAsync(collectionLink, item);
...
}
The CreateDocumentAsync
method specifies a Uri
argument that represents the collection the document should be inserted into, and an object
argument that represents the document to be inserted.
Replacing a Document in a Document Collection
Documents can be replaced in a document collection with the DocumentClient.ReplaceDocumentAsync
method:
public async Task SaveTodoItemAsync(TodoItem item, bool isNewItem = false)
{
...
await client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(Constants.DatabaseName, Constants.CollectionName, item.Id), item);
...
}
The ReplaceDocumentAsync
method specifies a Uri
argument that represents the document in the collection that should be replaced, and an object
argument that represents the updated document data.
Deleting a Document from a Document Collection
A document can be deleted from a document collection with the DocumentClient.DeleteDocumentAsync
method:
public async Task DeleteTodoItemAsync(string id)
{
...
await client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(Constants.DatabaseName, Constants.CollectionName, id));
...
}
The DeleteDocumentAsync
method specifies a Uri
argument that represents the document in the collection that should be deleted.
Deleting a Document Collection
A document collection can be deleted from a database with the DocumentClient.DeleteDocumentCollectionAsync
method:
await client.DeleteDocumentCollectionAsync(collectionLink);
The DeleteDocumentCollectionAsync
method specifies a Uri
argument that represents the document collection to be deleted. Note that invoking this method will also delete the documents stored in the collection.
Deleting a Database
A database can be deleted from an Azure Cosmos DB database account with the DocumentClient.DeleteDatabaesAsync
method:
await client.DeleteDatabaseAsync(UriFactory.CreateDatabaseUri(Constants.DatabaseName));
The DeleteDatabaseAsync
method specifies a Uri
argument that represents the database to be deleted. Note that invoking this method will also delete the document collections stored in the database, and the documents stored in the document collections.
Summary
This article explained how to use the Azure Cosmos DB .NET Standard client library to integrate an Azure Cosmos DB document database into a Xamarin.Forms application. An Azure Cosmos DB document database is a NoSQL database that provides low latency access to JSON documents, offering a fast, highly available, scalable database service for applications that require seamless scale and global replication.