CosmosDB is Microsoft’s new way of storing data in the cloud, comparing to good old MSSQL Server. It offers globally distributed, multi-model database. Interesting fact is that it offers multiple model of storing data: key-value, column-family, documents and graph as shown in this picture:
First you need a Cosmos DB account
Create a Cosmos DB account, then go to Keys tab – you will need PrimaryKey and EndpointUri.
Now go to Data Explorer and create a database and collection. I created Documents database and Messages collection.
Connecting to Cosmos DB
I’m developing my app in .NET Core and for that I need to install Microsoft.Azure.DocumentDB.Core nuget package. Then I created a DocumentDbService class, that will connect to application to Cosmos DB api.
public class DocumentDbService { private const string DatabaseName = "Documents"; private const string CollectionName = "Messages"; public async Task SaveDocumentAsync(DocumentDto document) { try { var client = new DocumentClient(new Uri(ConfigurationHelper.GetCosmosDbEndpointUri()), ConfigurationHelper.GetCosmosDbPrimaryKey()); await client.UpsertDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseName, CollectionName), document); } catch (Exception e) { Console.WriteLine("Error: {0}, Message: {1}", e.Message, e.GetBaseException().Message); } } }
ConfigurationHelper class is just a static class that gets EndpointUri and PrimaryKey as strings, so you can just paste them here directly. The code above will create a new document in Documents database and Messages collection.
DocumentDto is just a simple object that will be saved as json:
public class DocumentDto { public string StockId { get; set; } public string Name { get; set; } public float Price { get; set; } public DateTime UpdatedAt { get; set; } }
In order do use it in ASP.NET Core I created a controller:
public class MessagesController : Controller { [HttpPost] public async Task<IActionResult> Save([FromBody]SendMessageDto message) { try { var document = new DocumentDto { StockId = message.StockId, Name = message.Name, Price = message.Price, UpdatedAt = DateTime.UtcNow }; await new DocumentDbService().SaveDocumentAsync(document); return StatusCode(200); } catch (Exception e) { Console.WriteLine(e); return StatusCode(500, e.Message); } } }
Usage of it is very simple – it creates DocumentDto and store it in Cosmos DB database. To see the result you need to go to Azure’s Data Explorer and fetch for Messages like in a screen above.
Getting data from Cosmos DB with SQL api
Microsoft’s new storage api has ability to store data in a multiple formats. Let’s try getting the latest updates from Messages collection. In DocumentDbService class we need a part of code to get data:
public IQueryable<DocumentDto> GetLatestDocuments() { try { var client = new DocumentClient(new Uri(ConfigurationHelper.GetCosmosDbEndpointUri()), ConfigurationHelper.GetCosmosDbPrimaryKey()); return client.CreateDocumentQuery<DocumentDto>( UriFactory.CreateDocumentCollectionUri(DatabaseName, CollectionName), "SELECT * FROM Messages ORDER BY Messages.UpdatedAt desc", new FeedOptions { MaxItemCount = 10 }); } catch (Exception e) { Console.WriteLine("Error: {0}, Message: {1}", e.Message, e.GetBaseException().Message); return null; } }
This is where magic happens. As you can see I used plain old SQL query as it would be Messages table, but instead I queried json objects that does not necessary need to have UpdatedAt field.
Code in the controller is very simple.
[HttpGet] public IQueryable<DocumentDto> GetTenLatestUpdates() { try { var documents = new DocumentDbService().GetLatestDocuments(); return documents; } catch (Exception e) { Console.WriteLine(e); return null; } }
Notice that GetTenLatestUpdates controller method returns IQueryable interface that on web will be presented as json, but there is also a way to efficiently filter data with OData.