使用 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 中重新创建函数应用和相关资源。

注意

本文目前仅支持 Node.js v3 for Functions

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

配置环境

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

创建 Azure Cosmos DB 帐户

现在,创建一个 Azure Cosmos DB 帐户作为无服务器帐户类型。 这种基于消耗的模式让 Azure Cosmos DB 成为了无服务器工作负载的强有力选项。

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

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

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

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

创建 Azure Cosmos DB 数据库和容器

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

  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 选择
    输入新应用设置名称 键入 CosmosDbConnectionSetting
    输入“CosmosDbConnectionSetting”的值 粘贴复制的 Azure Cosmos DB 帐户的连接字符串。 还可以将 Microsoft Entra 标识配置为替代项。

    这会在 Azure 的函数应用中创建一个名为 connection CosmosDbConnectionSetting 的应用程序设置。 现在可以将此设置下载到 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.Functions.Worker.Extensions.CosmosDB

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

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

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  },
  "concurrency": {
    "dynamicConcurrencyEnabled": true,
    "snapshotPersistenceEnabled": true
  },
  "extensions": {
    "cosmosDB": {
      "connectionMode": "Gateway"
    }
  }
}

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

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

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

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

添加输出绑定

在 C# 类库项目中,绑定被定义为函数方法上的绑定属性。

打开 HttpExample.cs 项目文件并添加以下类:

    public class MultiResponse
    {
        [CosmosDBOutput("my-database", "my-container",
            Connection = "CosmosDbConnectionSetting", CreateIfNotExists = true)]
        public MyDocument Document { get; set; }
        public HttpResponseData HttpResponse { get; set; }
    }
    public class MyDocument {
        public string id { get; set; }
        public string message { get; set; }
    }

MyDocument 类定义一个会写入数据库的对象。 存储帐户的连接字符串由 Connection 属性设置。 在本例中,可以省略 Connection,因为你已使用默认存储帐户。

MultiResponse 类允许在 Azure Cosmos DB 中写入指定集合,并返回 HTTP 成功消息。 由于需要返回 MultiResponse 对象,因此还需更新方法签名。

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

绑定属性直接在函数代码中定义。 Azure Cosmos DB 输出配置描述了 Azure Cosmos DB 输出绑定必需的字段。

对于此 MultiResponse 方案,你需要向函数添加 extraOutputs 输出绑定。

app.http('HttpExample', {
  methods: ['GET', 'POST'],
  extraOutputs: [sendToCosmosDb],
  handler: async (request, context) => {

将以下属性添加到绑定配置:

const sendToCosmosDb = output.cosmosDB({
  databaseName: 'my-database',
  containerName: 'my-container',
  createIfNotExists: false,
  connection: 'CosmosDBConnectionString',
});

直接在 function_app.py 文件中定义绑定属性。 使用 cosmos_db_output 修饰器添加 Azure Cosmos DB 输出绑定

@app.cosmos_db_output(arg_name="outputDocument", database_name="my-database", 
    container_name="my-container", connection="CosmosDbConnectionSetting")

在此代码中,arg_name 标识代码中引用的绑定参数,database_namecontainer_name 是绑定写入到的数据库和集合名称,connection 是包含 Azure Cosmos DB 帐户连接字符串的应用程序设置的名称,该字符串位于 local.settings.json 文件的 CosmosDbConnectionSetting 设置中。

添加使用输出绑定的代码

使用下面的代码替换现有 Run 方法:

        [Function("HttpExample")]
        public static MultiResponse Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
            FunctionContext executionContext)
        {
            var logger = executionContext.GetLogger("HttpExample");
            logger.LogInformation("C# HTTP trigger function processed a request.");

            var message = "Welcome to Azure Functions!";

            var response = req.CreateResponse(HttpStatusCode.OK);
            response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
            response.WriteString(message);

            // Return a response to both HTTP trigger and Azure Cosmos DB output binding.
            return new MultiResponse()
            {
                 Document = new MyDocument
                {
                    id = System.Guid.NewGuid().ToString(),
                    message = message
                },
                HttpResponse = response
            };
        }

添加使用 context 上的 extraInputs 输出绑定对象将 JSON 文档发送到命名输出绑定函数 sendToCosmosDb 的代码。 请在 return 语句之前添加此代码。

      context.extraOutputs.set(sendToCosmosDb, {
        // create a random ID
        id:
          new Date().toISOString() + Math.random().toString().substring(2, 10),
        name: name,
      });

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

const { app, output } = require('@azure/functions');

const sendToCosmosDb = output.cosmosDB({
  databaseName: 'my-database',
  containerName: 'my-container',
  createIfNotExists: false,
  connection: 'CosmosDBConnectionString',
});

app.http('HttpExampleToCosmosDB', {
  methods: ['GET', 'POST'],
  extraOutputs: [sendToCosmosDb],
  handler: async (request, context) => {
    try {
      context.log(`Http function processed request for url "${request.url}"`);

      const name = request.query.get('name') || (await request.text());

      if (!name) {
        return { status: 404, body: 'Missing required data' };
      }

      // Output to Database
      context.extraOutputs.set(sendToCosmosDb, {
        // create a random ID
        id:
          new Date().toISOString() + Math.random().toString().substring(2, 10),
        name: 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.';

      // Return to HTTP client
      return { body: responseMessage };
    } catch (error) {
      context.log(`Error: ${error}`);
      return { status: 500, body: 'Internal Server Error' };
    }
  },
});

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

按以下代码所示更新 HttpExample\function_app.py。 将 outputDocument 参数添加到函数定义,并将 outputDocument.set() 添加到 if name: 语句下:

import azure.functions as func
import logging

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="hello", auth_level=func.AuthLevel.ANONYMOUS)
@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")
@app.cosmos_db_output(arg_name="outputDocument", database_name="my-database", container_name="my-container", connection="CosmosDbConnectionSetting")
def test_function(req: func.HttpRequest, msg: func.Out[func.QueueMessage],
    outputDocument: func.Out[func.Document]) -> func.HttpResponse:
     logging.info('Python HTTP trigger function processed a request.')
     logging.info('Python Cosmos DB trigger function processed a request.')
     name = req.params.get('name')
     if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

     if name:
        outputDocument.set(func.Document.from_dict({"id": name}))
        msg.set(name)
        return func.HttpResponse(f"Hello {name}!")
     else:
        return func.HttpResponse(
                    "Please pass a name on the query string or in the request body",
                    status_code=400
                )

文档 {"id": "name"} 在绑定中指定的数据库集合中创建。

在本地运行函数

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: