使用 Cosmos DB 在 Azure 上创建无服务器 REST API(第二部分)- 创建和更新操作
扩展我们的无服务器 REST API
扩展我们的无服务器 REST API
如果您还没有阅读,建议先阅读我之前的博客文章,其中详细介绍了如何配置 Azure Function 和 Cosmos DB,向数据库添加数据以及创建返回 Cosmos DB 集合数据的基本 HTTP 触发器函数。
在本文中,我们将扩展我们在上一个应用程序中创建的函数,添加一个函数来向我们的 Cosmos DB 实例添加和更新记录。我们还将把代码从 Azure Portal 中的 IDE 迁移出来,并在 Visual Studio 中使用 Function SDK。使用 Visual Studio 极具优势,因为它提供了许多工具来提高生产力和源代码控制集成。
安装 Azure Functions SDK
首先,您需要安装 Visual Studio (如果您还没有),并获取 SDK。这可以通过导航到“工具”→“扩展和更新”来实现。在左侧窗格中,单击“联机”,然后搜索并安装“Azure Functions and Web Job Tools”。此扩展将安装您在 Visual Studio 中构建和部署 Azure Functions 所需的所有工具。
创建函数解决方案
安装 Azure Function SDK 后,我们现在可以创建一个函数项目。您可以通过导航到“文件”→“新建项目”→搜索“Azure Functions”并选择第一个结果 → 为项目命名并选择位置 → 单击“确定”来完成此操作。
下一个提示确认函数的触发器设置。在此示例中,我们将选择在我之前的文章中创建的存储帐户 (如果您没有 Azure 帐户,可以使用模拟器)。对于触发器本身,我们将创建一个匿名 HTTP 触发器。请确保从顶部的下拉列表中选择了 Azure Functions v1 - 在撰写本文时,.NET Standard 的 Azure Functions v2 仍处于预览状态。
创建函数后,我们将首先需要导入所需的 nuget 包,其中包括 Newtonsoft - 一个用于在 .NET 中处理 JSON 的库,以及用于 Cosmos DB 接口的扩展。为了做到这一点,我们需要编辑解决方案中的 .csproj 文件。这可以通过右键单击解决方案资源管理器中的项目并单击“编辑 YOUR_PROJECT_NAME.csproj”来实现。
打开项目文件进行编辑后,将程序包引用修改为如下所示:
<ItemGroup>
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.DocumentDB" Version="1.2.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.13" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.10" />
</ItemGroup>
尝试重新生成解决方案,以确保 nuget 包能够正确还原而不会出错。您可能会注意到 Visual Studio 会给出关于 Newtonsoft.Json 版本约束的警告,有趣的是,在 Microsoft.NET.Sdk.Functions
nuget 项目中,Newtonsoft.Json 的 9.0.1 版本被标记为必需。通过在 GitHub 的各种问题线程中阅读在线资料,有人表示这是因为在某些情况下存在运行时错误;然而,我没有发现任何与使用 11.0.2 版本相关的问题,所以我认为忽略此警告是安全的。如果您确实遇到了任何问题,请告诉我!
创建函数
现在我们已经导入了所需的 nugets,我们可以开始创建我们的第一个 Azure Function 类了。我们要创建的第一项功能是一个简单的 GET
方法,它将返回我们 Cosmos DB posts 集合中的所有记录 (类似于我在上一篇文章中创建的)。我们需要做的第一件事是重命名函数解决方案中创建的现有类文件,在此示例中,我将其命名为“GetPosts
”。以下是函数的代码 (修改代码以输入您自己的 Cosmos DB 实例的详细信息)。
public static class GetPosts
{
[FunctionName("GetPosts")]
public static HttpResponseMessage Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)]
HttpRequestMessage req,
TraceWriter log,
[DocumentDB("YOUR_COSMOS_DB_INSTANCE_NAME", "posts",
ConnectionStringSetting = "CosmosDbConnection")]
IEnumerable<object> posts)
{
return req.CreateResponse(HttpStatusCode.OK, posts);
}
}
此代码中有一些您可能不熟悉的内容,特别是如果您之前只使用 Azure IDE 创建过函数。首先,输入参数具有确定授权级别、路由和数据库连接字符串等设置的属性。请注意,我们的一个输入参数是一个 posts 连接,代表我们 Cosmos DB 集合中的所有项目。为了连接到我们的数据库,我们需要指定 Azure 门户中提供的 Cosmos DB 连接字符串,并将其复制到我们项目中的 local.settings.json 文件中。
您的 local.settings.json 文件应该看起来类似。您可以在 Azure 门户的“Keys
”下找到您的 Cosmos DB 实例连接字符串。
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "YOUR_STORAGE_ACCOUNT_CONNECTION_STRING",
"AzureWebJobsDashboard": "YOUR_STORAGE_ACCOUNT_CONNECTION_STRING",
"CosmosDbConnection": "YOUR_COSMOS_DB_CONNECTION_STRING"
}
}
一切就绪后,我们现在就可以测试我们的函数了。按 F5 运行函数。以下控制台窗口应显示我们函数的终结点 URL。
为了向我们的 API 发送请求以检索数据,我们将使用一个名为 Postman 的工具。首先,下载该应用程序,选择 GET
作为方法调用,在控制台窗口中输入 URL,然后按发送按钮。
如果您在 posts 集合中有任何记录,您应该会在结果窗口中看到它们,以及 200 (OK) 的状态码。
我们要创建的第二个函数具有在数据库中创建和更新帖子的功能。与我们之前的函数一样,通过右键单击项目文件并单击“添加”→“新项”,搜索 Azure Function 并将其命名为“CreateOrUpdatePost
”,来创建一个新的类文件。同样,我们将创建一个匿名的 Http 触发器。
这是我们创建或更新函数的代码
public static class CreateOrUpdatePost
{
[FunctionName("CreateOrUpdatePost")]
public static HttpResponseMessage Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "put", "post", Route = null)]
HttpRequestMessage req,
TraceWriter log,
[DocumentDB("YOUR_COSMOS_DB_INSTANCE_NAME", "posts", Id = "id",
ConnectionStringSetting = "CosmosDbConnection")] out object post)
{
try
{
var requestBody = req.Content.ReadAsStringAsync();
var generator = new JSchemaGenerator();
var schema = generator.Generate(typeof(Post));
var rawPost = requestBody.Result;
var isPost = JObject.Parse(rawPost).IsValidJson(schema);
if (isPost)
{
var deserializePost = JsonConvert.DeserializeObject<Post>(rawPost);
post = new {
userId = deserializePost.UserId.ToString(),
id = deserializePost.Id.ToString(),
title = deserializePost.Title,
body = deserializePost.Body };
return req.CreateResponse(HttpStatusCode.OK, post);
}
post = null;
return req.CreateResponse(HttpStatusCode.BadRequest,
"Please pass a post on the query string or in the request body");
}
catch (Exception ex)
{
post = null;
return req.CreateResponse(HttpStatusCode.InternalServerError,
$"The following error occurred: {ex.Message}");
}
}
}
public static class ValidateJson
{
public static bool IsValidJson(this JObject jObject, JSchema jSchema)
{
return jObject.IsValid(jSchema);
}
}
public class Post
{
[JsonProperty(PropertyName = "userId")]
public int UserId { get; set; }
[JsonProperty(PropertyName = "id")]
public int Id { get; set; }
[JsonProperty(PropertyName = "title")]
public string Title { get; set; }
[JsonProperty(PropertyName = "body")]
public string Body { get; set; }
}
此代码的工作原理是获取 JSON 格式的帖子,然后将原始 JSON 与我们的帖子架构进行验证,如果匹配成功,它将添加或更新记录 (如果集合中已有 ID 匹配的帖子)。同样,我们可以使用 Postman 来测试此函数。开始调试应用程序并复制终结点地址。
打开 Postman 并选择 POST
或 PUT
作为 HTTP 方法,然后将终结点地址粘贴到 URL 部分。接下来单击“Body”选项卡,选择“raw”单选按钮,并将以下帖子 JSON 粘贴到文本部分。
{
"userId" : 8,
"id" : 123,
"title" : "hello",
"body" : "world"
}
然后按“Send”按钮。您应该会收到一个包含 200 (OK) 状态码的响应。
接下来重新运行我们的“GetPosts
”方法,根据您之前是否在数据库中有一个 ID 为 123 的帖子,您应该会在我们的 Cosmos DB 集合中看到您的帖子。
总结
这结束了我关于使用 Azure 中的 Cosmos DB 创建基本无服务器 HTTP API 的两部分系列。我在这里展示的只是使用 Azure 中的无服务器功能所能实现的冰山一角。可能性是无限的!如果您有任何问题,请通过本文的评论部分与我联系,我很乐意为您提供帮助。