diff --git a/AzureFunctionsTodo/TodoApiCosmosDb.cs b/AzureFunctionsTodo/TodoApiCosmosDb.cs index 455aa7f..26359a7 100644 --- a/AzureFunctionsTodo/TodoApiCosmosDb.cs +++ b/AzureFunctionsTodo/TodoApiCosmosDb.cs @@ -9,6 +9,7 @@ using System.Linq; using System; using System.Collections.Generic; +using Microsoft.Azure.Documents.Client; namespace AzureFunctionsTodo { @@ -24,14 +25,16 @@ public static class TodoApiCosmosDb databaseName: "tododb", collectionName: "tasks", ConnectionStringSetting = "CosmosDBConnection")] - IAsyncCollector todos, TraceWriter log) + IAsyncCollector todos, TraceWriter log) { log.Info("Creating a new todo list item"); string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); var input = JsonConvert.DeserializeObject(requestBody); var todo = new Todo() { TaskDescription = input.TaskDescription }; - await todos.AddAsync(todo); + //the object we need to add has to have a lower case id property or we'll + // end up with a cosmosdb document with two properties - id (autogenerated) and Id + await todos.AddAsync(new { id = todo.Id, todo.CreatedTime, todo.IsCompleted, todo.TaskDescription }); return new OkObjectResult(todo); } @@ -70,42 +73,57 @@ public static class TodoApiCosmosDb [FunctionName("CosmosDb_UpdateTodo")] public static async Task UpdateTodo( [HttpTrigger(AuthorizationLevel.Anonymous, "put", Route = route + "/{id}")]HttpRequest req, - [CosmosDB(databaseName: "tododb", collectionName: "tasks", ConnectionStringSetting = "CosmosDBConnection", - Id = "{id}")] Todo todo, + [CosmosDB(ConnectionStringSetting = "CosmosDBConnection")] + DocumentClient client, TraceWriter log, string id) { - string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); var updated = JsonConvert.DeserializeObject(requestBody); - if (todo == null) + Uri collectionUri = UriFactory.CreateDocumentCollectionUri("tododb", "tasks"); + var document = client.CreateDocumentQuery(collectionUri).Where(t => t.Id == id) + .AsEnumerable().FirstOrDefault(); + if (document == null) { return new NotFoundResult(); } - todo.IsCompleted = updated.IsCompleted; + + document.SetPropertyValue("IsCompleted", updated.IsCompleted); if (!string.IsNullOrEmpty(updated.TaskDescription)) { - todo.TaskDescription = updated.TaskDescription; + document.SetPropertyValue("TaskDescription", updated.TaskDescription); } - // update not implemented yet + await client.ReplaceDocumentAsync(document); - return new OkObjectResult(todo); + /* var todo = new Todo() + { + Id = document.GetPropertyValue("id"), + CreatedTime = document.GetPropertyValue("CreatedTime"), + TaskDescription = document.GetPropertyValue("TaskDescription"), + IsCompleted = document.GetPropertyValue("IsCompleted") + };*/ + + // an easier way to deserialize a Document + Todo todo2 = (dynamic)document; + + return new OkObjectResult(todo2); } [FunctionName("CosmosDb_DeleteTodo")] - public static IActionResult DeleteTodo2( + public static async Task DeleteTodo( [HttpTrigger(AuthorizationLevel.Anonymous, "delete", Route = route + "/{id}")]HttpRequest req, - [CosmosDB(databaseName: "tododb", collectionName: "tasks", ConnectionStringSetting = "CosmosDBConnection", - Id = "{id}")] Todo todo, + [CosmosDB(ConnectionStringSetting = "CosmosDBConnection")] DocumentClient client, TraceWriter log, string id) { - - if (todo == null) + Uri collectionUri = UriFactory.CreateDocumentCollectionUri("tododb", "tasks"); + var document = client.CreateDocumentQuery(collectionUri).Where(t => t.Id == id) + .AsEnumerable().FirstOrDefault(); + if (document == null) { return new NotFoundResult(); } - // delete not implemented - may need to bind to DocumentClient + await client.DeleteDocumentAsync(document.SelfLink); return new OkResult(); } } diff --git a/README.md b/README.md index 705dc2b..c80021b 100644 --- a/README.md +++ b/README.md @@ -7,4 +7,19 @@ A simple CRUD (Create, Read, Update, Delete) API is created to manage TODO items - table storage - CosmosDb -It's implemented using Azure Functions V2 in C#, and can be run against the local storage emulator for table storage, and the CosmosDb emulator. \ No newline at end of file +It's implemented using Azure Functions V2 in C#, and can be run against the local storage emulator for table storage, and the CosmosDb emulator. + + +You'll need to set up a `local.settings.json` file containing connection strings for the Azure Storage and Azure CosmosDb emulators + +```js +{ + "IsEncrypted": false, + "Values": { + "AzureWebJobsStorage": "UseDevelopmentStorage=true", + "AzureWebJobsDashboard": "UseDevelopmentStorage=true", + "FUNCTIONS_WORKER_RUNTIME": "dotnet", + "CosmosDBConnection": "AccountEndpoint=https://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==" + } +} +``` \ No newline at end of file