4 Cosmos DB Repository Class - adamhockemeyer/Azure-Functions---CosmosDB-ResourceToken-Broker GitHub Wiki

Cosmos DB Repository Class

The Cosmos DB Repository Class was created as a .Net Standard Multi-Target Library so that it can be consumed and used in multiple ways.

Why would I use this?


The repository class is a wrapper around the .net framework and .net standard Cosmos DB client libraries that will reduce the amount of code in your product by eliminating repeat code.

This class also has a fluent style api for setting up your client to make calls to your Cosmos DB. Finally, this class also has a subclass called TypedDocument<T> which by default will add the C# POCO object type name into the document as well as a default partition key property of "_pk". The TypedDocument<T> is for convince making it easy for the repository to query the Cosmos DB collection for documents of a certain type (i.e. get me documents of type Dog of certain breed).

How to Use


Each of the API projects included in this repo have an Azure Function class named Dog.cs. For a quick usage example, you can see how the Cosmos DB Repository is used there.

1 - Setup

The CosmosDBRepository is setup as a singleton class, simply include the code in your project and then you can get an instance by calling:

CosmosDBRepository.Instance

Now lets use the Fluent API on this singleton to setup our connection as a client to talk to Cosmos DB.

Lets setup the repository at the top of your class that you want to use it.

static CosmosDBRepository repo = CosmosDBRepository.Instance
                .Endpoint(GetEnvironmentVariable("cosmosDBEndpoint"))
                .Database(cosmosDatabase)`
                .Collection(cosmosCollection);

Example of property values:

Property Note Example
cosmosDBEndpoint URL to your Cosmos DB https://{account-name}.documents.azure.com:443/
cosmosDatabase Cosmos DB database name db
cosmosCollection Cosmos DB Collection in the database dataCollection

2 - Resource Token and Partition Key

Our repository class is almost setup to use. The last piece that we need to add to the instance is our resource token. First we would need the client to authenticate with the provider, a client SDK can help with this (i.e. Microsoft.Azure.Mobile.Client), and once the client is authenticated, the client would then call the Azure Function that we created with the token received from the authentication, and get a resource token from the Azure Function.

Once you have the resource token, you can set it for your CosmosDBRepository by simply calling:

repo.AuthKeyOrResourceToken(resourceToken);

// or

CosmosDBRepository.Instance.AuthKeyOrResourceToken(resourceToken);

Finally, if you are using the Repository and following along with this example, you will need to set the Partition Key to help out the repository when working with Cosmos DB. Partition Keys are an important topic and can be referenced at the official docs. In short, partition keys are used to help your application scale and reach massive throughput with reads/writes, data in a specific partition key is limited to 10GB (so pick your partition key wisely), and a partition key can be used in a permission to restrict a users access to only their partition or group of partitions.

For reference, this is what the properties of the permission look like that gets created by the resource broker function.

permission = new Permission
                    {
                        // This can be "All" or "Read"
                        PermissionMode = permissionMode, 
                        ResourceLink = collection.SelfLink,
                        // Permission restricts access to this partition key
                        ResourcePartitionKey = new PartitionKey(userId),
                        // Unique per user
                        Id = permissionId   
                    };

So for our example, we also need to set the partition key for the repository.

// Set the partition key, so the user has access to their documents, based on the permission that was setup
// by using the userid as a permission key.  A client could just set this once initially.
repo.PartitionKey(userId);

That's it! Set your Cosmos DB Endpoint, database, collection, resource token, partition key and you are off to the races.

3 - Usage Examples

Now since we used the repository wrapper over the client sdk, data access calls are dead simple as shown below.

// Create/Update a new Dog in the collection
Dog dog = await repo.UpsertItemAsync<Dog>(new Dog { Breed = dogBreed, Name = dogName });

// Get all dogs (that you have access to based on your permission in your resource token)
var dogs = await repo.GetAllItemsAsync<Dog>();

// Or get dogs of a specific breed.
var dogs = await repo.GetItemsAsync<Dog>(p => p.Breed == "Gooldendoodle");

// Or remove a dog by document id or the previously retrieved document
await repo.RemoveItemAsync<Dog>(dog);

When creating new models or POCO's to use with Cosmos DB, you simply need to make your new model/POCO inherit from 'TypedDocument', where T is the type of the class.

For example:

    public class Dog : TypedDocument<Dog>
    {
        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("breed")]
        public string Breed { get; set; }

    }

A class that inherits from TypedDocument is expected by the repository to enable querying by document type and with the Partition Key Fluent API that is setup.

Feel free to checkout the code for other methods.

This is a simply repository that you can download, use and modify to your liking.

⚠️ **GitHub.com Fallback** ⚠️