使用 Visual Studio Code 将 Azure Functions 连接到 Azure Cosmos DB

无需编写自己的集成代码,即可使用 Azure Functions 将 Azure 服务和其他资源连接到函数。 这些绑定表示输入和输出,在函数定义中声明。 绑定中的数据作为参数提供给函数。 触发器是一种特殊类型的输入绑定。 尽管一个函数只有一个触发器,但它可以有多个输入和输出绑定。 有关详细信息,请参阅 Azure Functions 触发器和绑定的概念

本文介绍如何使用 Visual Studio Code 将 Azure Cosmos DB 连接到在前一篇快速入门文章中创建的函数。 添加到此函数的输出绑定会将 HTTP 请求中的数据写入到存储在 Azure Cosmos DB 容器中的 JSON 文档。

在开始之前,必须先完成快速入门:使用 Visual Studio Code 在 Azure 中创建 C# 函数。 如果在该文章结束时清理了资源,请再次执行相应的步骤,以在 Azure 中重新创建函数应用和相关资源。

在开始之前,必须先完成快速入门:使用 Visual Studio Code 在 Azure 中创建 JavaScript 函数。 如果在该文章结束时清理了资源,请再次执行相应的步骤,以在 Azure 中重新创建函数应用和相关资源。

配置环境

在开始之前,请确保安装适用于 Visual Studio Code 的 Azure 数据库扩展

创建 Azure Cosmos DB 帐户

重要

Azure Cosmos DB 无服务器现已正式发布。 这种基于消耗的模式让 Azure Cosmos DB 成为了无服务器工作负载的强有力选项。 要在无服务器模式下使用 Azure Cosmos DB,请在创建帐户时选择“无服务器”作为“容量模式”。

  1. 在 Visual Studio Code 中,选择“查看>命令托盘...”,然后在命令托盘中搜索 Azure Databases: Create Server...

  2. 根据提示提供以下信息:

    Prompt 选择
    选择 Azure 数据库服务器 选择“Azure Cosmos DB for NoSQL”以创建一个文档数据库,然后可以使用 SQL 语法来查询。 详细了解 Azure Cosmos DB for NoSQL
    帐户名称 输入标识此 Azure Cosmos DB 帐户的唯一名称。 帐户名称只能使用小写字母、数字及连字符 (-),必须为 3 到 31 个字符长。
    选择容量模型 选择“无服务器”以在无服务器模式下创建帐户。
    选择新资源的资源组 选择在前面的文章中创建函数应用的资源组。
    选择新资源的位置 选择用于托管 Azure Cosmos DB 帐户的地理位置。 使用离你或你的用户最近的位置,以便能够以最快的速度访问数据。

    预配新帐户后,通知区域会显示一条消息。

创建 Azure Cosmos DB 数据库和容器

  1. 在“活动”栏中选择 Azure 图标,展开“资源>Azure Cosmos DB”,右键单击(ctrl+单击 macOS)帐户,然后选择“创建数据库...”。

  2. 根据提示提供以下信息:

    Prompt 选择
    数据库名称 键入 my-database
    输入集合的 ID 键入 my-container
    输入集合的分区键 键入 /id 作为 分区键
  3. 选择“确定”来创建容器和数据库。

更新函数应用设置

前一篇快速入门文章中,你已在 Azure 中创建了一个函数应用。 在本文中,你将学习如何更新应用,以在刚刚创建的 Azure Cosmos DB 容器中写入 JSON 文档。 要连接到 Azure Cosmos DB 帐户,必须将其连接字符串添加到应用设置。 然后,将新设置下载到 local.settings.json 文件,这样就可以在本地运行时可以连接到 Azure Cosmos DB 帐户。

  1. 在 Visual Studio Code 中,右键单击(在 macOS 上按 Ctrl 并单击)新的 Azure Cosmos DB 帐户,然后选择“复制连接字符串”。

    复制 Azure Cosmos DB 连接字符串

  2. F1 键打开命令面板,然后搜索并运行命令 Azure Functions: Add New Setting...

  3. 选择你在前一篇文章中创建的函数应用。 根据提示提供以下信息:

    Prompt 选择
    输入新应用设置名称 键入 CosmosDbConnectionString
    输入“CosmosDbConnectionString”的值 粘贴你刚刚复制的 Azure Cosmos DB 帐户的连接字符串。

    这会在 Azure 的函数应用中创建一个名为 connection CosmosDbConnectionString 的应用程序设置。 现在可以将此设置下载到 local.settings.json 文件中。

  4. 再次按 F1 键打开命令面板,然后搜索并运行命令 Azure Functions: Download Remote Settings...

  5. 选择你在前一篇文章中创建的函数应用。 选择“全是”覆盖现有本地设置。

这会将 Azure 中的所有设置下载到本地项目,包括新的连接字符串设置。 下载的大多数设置不会在本地运行时使用。

注册绑定扩展

由于你使用 Azure Cosmos DB 输出绑定,因此在运行项目之前,必须安装对应的绑定扩展。

除了 HTTP 和计时器触发器,绑定将实现为扩展包。 在终端窗口中运行以下 dotnet add package 命令,将 Azure Cosmos DB 扩展包添加到项目中。

dotnet add package Microsoft.Azure.WebJobs.Extensions.CosmosDB 

项目已配置为使用扩展捆绑包,因此会自动安装一组预定义的扩展包。

在项目根目录下的 host.json 文件中启用扩展捆绑包,如下所示:

{
  "version": "2.0",
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[1.*, 2.0.0)"
  } 
}

现在,你可以将 Azure Cosmos DB 输出绑定添加到项目。

添加输出绑定

在 Functions 中,每种类型的绑定都需要一个 directiontype,以及要在 function.json 文件中定义的唯一 name。 定义这些属性的方式取决于函数应用的语言。

在 C# 类库项目中,绑定被定义为函数方法上的绑定属性。 然后,基于这些属性自动生成 Functions 所需的 function.json 文件。

打开 HttpExample.cs 项目文件,并将以下参数添加到 方法定义中:

            [CosmosDB(databaseName: "my-database", collectionName: "my-container",
                ConnectionStringSetting = "CosmosDbConnectionString"
                )]IAsyncCollector<dynamic> documentsOut,

documentsOut 参数是一个 IAsyncCollector<T> 类型,它表示在函数完成时将写入到 Azure Cosmos DB 容器的 JSON 文档的集合。 特定属性指示容器及其父数据库的名称。 Azure Cosmos DB 帐户的连接字符串是由 ConnectionStringSettingAttribute 设置。

特定属性指定容器的名称及其父数据库的名称。 Azure Cosmos DB 帐户的连接字符串是由 CosmosDbConnectionString 设置。

直接在 function.json 文件中定义绑定属性。 根据绑定类型,可能还需要其他属性。 Azure Cosmos DB 输出配置描述了 Azure Cosmos DB 输出绑定必需的字段。 扩展可以轻松地将绑定添加到 function.json 文件。

要创建绑定,请右键单击(在 macOS 系统上,请按住 Ctrl 并单击)HttpTrigger 文件夹中的 function.json 文件,并选择“添加绑定...”。请按照提示为新绑定定义以下绑定属性:

Prompt Value 说明
选择绑定方向 out 该绑定是输出绑定。
选择方向为“out”的绑定 Azure Cosmos DB 绑定是 Azure Cosmos DB 绑定。
用于在代码中标识此绑定的名称 outputDocument 用于标识代码中引用的绑定参数的名称。
要在其中写入数据的 Azure Cosmos DB 数据库 my-database 包含目标容器的 Azure Cosmos DB 数据库的名称。
要在其中写入数据的数据库集合 my-container 将在其中写入 JSON 文档的 Azure Cosmos DB 容器的名称。
如果为 true,则创建 Azure Cosmos DB 数据库和集合 false 目标数据库和容器已存在。
从 local.setting.json 中选择设置 CosmosDbConnectionString 包含 Azure Cosmos DB 帐户连接字符串的应用程序设置的名称。
分区键(可选) 留空 仅当输出绑定创建容器时才是必需的。
集合吞吐量(可选) 留空 仅当输出绑定创建容器时才是必需的。

绑定将添加到 function.json 中的 bindings 数组,在删除所有存在的 undefined 值后应如下所示:

{
    "type": "cosmosDB",
    "direction": "out",
    "name": "outputDocument",
    "databaseName": "my-database",
    "collectionName": "my-container",
    "createIfNotExists": "false",
    "connectionStringSetting": "CosmosDbConnectionString"
}

添加使用输出绑定的代码

添加使用 documentsOut 输出绑定对象来创建 JSON 文档的代码。 请在方法返回之前添加此代码。

if (!string.IsNullOrEmpty(name))
{
    // Add a JSON document to the output container.
    await documentsOut.AddAsync(new
    {
        // create a random ID
        id = System.Guid.NewGuid().ToString(),
        name = name
    });
}

此时,你的函数应如下所示:

[FunctionName("HttpExample")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
    [CosmosDB(
        databaseName: "my-database",
        collectionName: "my-container",
        ConnectionStringSetting = "CosmosDbConnectionString")]IAsyncCollector<dynamic> documentsOut,
    ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string name = req.Query["name"];

    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
    dynamic data = JsonConvert.DeserializeObject(requestBody);
    name = name ?? data?.name;

    if (!string.IsNullOrEmpty(name))
    {
        // Add a JSON document to the output container.
        await documentsOut.AddAsync(new
        {
            // create a random ID
            id = System.Guid.NewGuid().ToString(),
            name = name
        });
    }

    string responseMessage = string.IsNullOrEmpty(name)
        ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
        : $"Hello, {name}. This HTTP triggered function executed successfully.";

    return new OkObjectResult(responseMessage);
}

添加在 context.bindings 上使用 outputDocument 输出绑定对象来创建 JSON 文档的代码。 请在 context.res 语句之前添加此代码。

if (name) {
    context.bindings.outputDocument = JSON.stringify({
        // create a random ID
        id: new Date().toISOString() + Math.random().toString().substring(2, 10),
        name: name
    });
}

此时,你的函数应如下所示:

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    const name = (req.query.name || (req.body && req.body.name));
    const responseMessage = name
        ? "Hello, " + name + ". This HTTP triggered function executed successfully."
        : "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.";

    if (name) {
        context.bindings.outputDocument = JSON.stringify({
            // create a random ID
            id: new Date().toISOString() + Math.random().toString().substring(2, 10),
            name: name
        });
    }

    context.res = {
        // status: 200, /* Defaults to 200 */
        body: responseMessage
    };
}

此代码现在将返回一个包含文档和 HTTP 响应的 MultiResponse 对象。

在本地运行函数

Visual Studio Code 与 Azure Functions Core Tools 相集成,便于你在发布到 Azure 之前在本地开发计算机上运行此项目。

  1. 若要调用函数,请按 F5 启动函数应用项目。 “终端”面板将显示 Core Tools 的输出。 应用将在“终端”面板中启动。 可以看到 HTTP 触发函数的 URL 终结点在本地运行。

    本地函数 Visual Studio Code 输出的屏幕截图。

    如果在 Windows 上运行时遇到问题,请确保用于 Visual Studio Code 的默认终端未设置为“WSL Bash”。

  2. 运行 Core Tools 后,转到“Azure: Functions”区域。 在“Functions”下,展开“本地项目”>“Functions” 。 右键单击 (Windows) 或按 Ctrl - 单击 (macOS) HttpExample 函数,然后选择“立即执行函数...”。

    Visual Studio Code 中的“立即执行函数”的屏幕截图。

  3. 在“输入请求正文”中,按 Enter 向函数发送请求消息。

  4. 当函数在本地执行并返回响应时,Visual Studio Code 中将引发通知。 函数执行的相关信息将显示在“终端”面板中。

  5. 按 Ctrl + C 停止 Core Tools 并断开调试器的连接

在本地运行函数

  1. 与上一篇文章中所述,按 F5 启动函数应用项目和 Core Tools。

  2. 运行 Core Tools 后,转到“Azure:Functions”区域。 在“Functions”下,展开“本地项目”>“Functions” 。 右键单击 HttpExample 函数(在 Mac 按 Ctrl-单击),然后选择“立即执行函数...”。

    立即在 Visual Studio Code 中执行函数

  3. 在“输入请求正文”中,你将看到请求消息正文值 。 按 Enter 将此请求消息发送给函数。

  4. 返回响应后,按 Ctrl + C 停用 Core Tools。

验证是否已创建 JSON 文档

  1. 在 Azure 门户上,返回到 Azure Cosmos DB 帐户并选择“数据资源管理器”。

  2. 展开数据库和容器,然后选择“项”以出容器中已经创建的文档。

  3. 验证输出绑定是否已创建新的 JSON 文档。

    验证是否已在 Azure Cosmos DB 容器中创建了新文档

重新部署并验证更新的应用

  1. 在 Visual Studio Code 中,按 F1 键打开命令面板。 在命令面板中,搜索并选择 Azure Functions: Deploy to function app...

  2. 选择你在第一篇文章中创建的函数应用。 由于你要将项目重新部署到同一个应用,因此请选择“部署”以关闭关于覆盖文件的警告。

  3. 部署完成后,可再次使用“立即执行函数...”功能在 Azure 中触发该函数。

  4. 再次检查在 Azure Cosmos DB 容器中创建的文档,确认输出绑定再次生成新的 JSON 文档。

清理资源

在 Azure 中,“资源”是指函数应用、函数、存储帐户等。 这些资源可以组合到资源组中,删除该组即可删除组中的所有内容。

已创建完成这些快速入门所需的资源。 这些资源可能需要付费,具体取决于帐户状态服务定价。 如果不再需要这些资源,请参阅下面介绍的资源删除方法:

  1. 在 Visual Studio Code 中,按 F1 打开命令面板。 在命令面板中,搜索并选择 Azure: Open in portal

  2. 选择你的函数应用,然后按 Enter。 随即将在 Azure 门户中打开函数应用页面。

  3. 在“概览”选项卡中,选择“资源组”旁边的命名链接。

    从函数应用页选择要删除的资源组的屏幕截图。

  4. 在“资源组”页上查看所包括的资源的列表,然后验证这些资源是否是要删除的。

  5. 选择“删除资源组”,然后按说明操作。

    可能需要数分钟才能删除完毕。 完成后会显示一个通知,持续数秒。 也可以选择页面顶部的钟形图标来查看通知。

后续步骤

已更新 HTTP 触发的函数,可将 JSON 文档写入 Azure Cosmos DB 容器。 现在,可以详细了解如何使用 Visual Studio Code 开发 Functions: