Docs 菜单
Docs 主页
/
MongoDB Atlas
/ /

Atlas Functions

在此页面上

  • 何时使用函数
  • 如何编写函数
  • 定义函数
  • 调用函数
  • 约束

Atlas Function是一段服务器端JavaScript代码,您写入该代码来定义应用程序的行为。您可以直接从客户端应用调用应用程序的函数,也可以定义自动集成和调用函数的服务。

函数可以调用其他函数,并包含用于处理MongoDB Atlas集群中数据的内置客户端。它们还包括有用的全局实用程序,支持常见的 Node.js内置模块,并且可以从npm注册表导入和使用外部包。

返回问候语的基本函数
exports = function(name) {
return `Hello, ${name ?? "stranger"}!`
}

函数是无服务器性质的

调用函数时,您的应用会将请求路由到托管应用服务器,该服务器评估您的代码并返回结果。此模型使 Functions 成为无服务器,这意味着您无需部署和管理服务器即可运行代码。相反,您需要写入函数源代码,然后由您的应用处理执行环境。

函数有上下文

函数在反映其执行环境的上下文中运行。上下文包括调用函数的用户、调用方式以及调用函数时应用的状态。您可以使用上下文来运行特定于用户的代码并与应用的其他部分配合使用。

要详细学习;了解如何使用函数上下文,请参阅上下文。

函数可以运行您定义的任意 JavaScript 代码,这意味着您几乎可以在任何情况下使用这些函数。常见使用案例包括低延迟、短时间运行的任务,如数据移动、转换和验证。您还可以使用它们连接外部服务,从客户端应用程序中抽象出实施细节。

触发器自动调用函数来处理特定事件。示例,每当数据库触发器观察到变更事件时,它就会将该变更事件作为参数来调用关联的函数。然后,您可以在触发器函数中访问权限变更事件的信息并做出适当响应。

注意

数据库触发器和定时触发器始终在系统用户的上下文中执行。

函数的代码本质上是一个已命名的JavaScript源文件,这意味着您可以在单个函数文件中定义多个JavaScript函数。该文件必须导出单个JavaScript函数以提供服务传入调用的入口点。按名称调用函数时,实际上是在调用函数源文件中分配给 exports的JavaScript函数。

示例,下面是一个简单的函数,它接受name参数、添加日志消息并为所提供的名称返回问候语:

exports = function Hello(name) {
console.log(`Said hello to ${name}`);
return `Hello, ${name}!`;
};

您可以使用现代 JavaScript 语法和导入包来定义更多复杂函数:

// You can use ES6 arrow functions
const uppercase = (str) => {
return str.toUpperCase();
};
// You can use async functions and await Promises
exports = async function GetWeather() {
// You can get information about the user called the function
const city = context.user.custom_data.city;
// You can import Node.js built-ins and npm packages
const { URL } = require("url");
const weatherUrl = new URL("https://example.com");
weatherUrl.pathname = "/weather";
weatherUrl.search = `?location="${city}"`;
// You can send HTTPS requests to external services
const weatherResponse = await context.http.get({
url: url.toString(),
headers: {
Accept: ["application/json"],
},
});
const { current, forecasts } = JSON.parse(weatherResponse.body.text());
return [
`Right now ${uppercase(city)} is ${current.temperature}°F and ${current.weather}.`,
`Here's the forecast for the next 7 days:`,
forecasts
.map((f) => `${f.day}: ${f.temperature}°F and ${f.weather}`)
.join("\n "),
].join("\n");
};
Right now NEW YORK CITY is 72°F and sunny.
Here's the forecast for the next 7 days:
Tuesday: 71°F and sunny
Wednesday: 72°F and sunny
Thursday: 73°F and partly cloudy
Friday: 71°F and rainy
Saturday: 77°F and sunny
Sunday: 76°F and sunny
Monday: 74°F and sunny

函数会自动将返回的值序列化为扩展 JSON 。这对于保留类型信息很有用,但可能不是应用程序所期望的。

例如,从以下函数返回的对象中的值将转换为结构化 EJSON 值:

exports = function() {
return {
pi: 3.14159,
today: new Date(),
}
}
{
"pi": {
"$numberDouble": "3.14159"
},
"today": {
"$date": {
"$numberLong": "1652297239913"
}
}
}

要返回标准 JSON 形式的值,请对该值调用 JSON.stringify(),然后返回字符串化后的结果:

exports = function() {
return JSON.stringify({
pi: 3.14159,
today: new Date(),
})
}
"{\"pi\":3.14159,\"today\":\"2022-05-11T19:27:32.207Z\"}"

您可以通过Atlas用户界面或通过使用App Services CLI或 GitHub部署导入函数配置和源代码来创建和管理应用程序中的函数。

您可以从Atlas用户界面定义新的服务器端函数:

1
  1. 导航至Triggers页面:

    1. 如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含项目的组织。

    2. 如果尚未显示,请从导航栏的 Projects 菜单中选择您的项目。

    3. 在侧边栏中,单击Services标题下的Triggers

      此时将显示“触发器”页面。

  2. 单击 Linked App Service: Triggers(管理员)链接。

  3. 在侧边栏中,单击Build标题下的Functions

  4. 单击Create a Function 。默认显示Settings标签页。

2

Name字段中输入函数的名称。对于应用程序中的所有其他函数,此名称必须是唯一的。

提示

您可以在嵌套文件夹内定义函数。函数名称是以斜线分隔的路径,因此名为utils/add的函数会映射到应用配置文件中的functions/utils/add.js

3

Atlas中的函数始终在特定应用程序用户的上下文中执行,或作为绕过规则的系统用户执行。要配置函数的执行用户,请指定Atlas应使用的身份验证类型。

注意

数据库函数和定时触发器始终在系统用户上下文中执行。

身份验证类型
说明
应用程序身份验证(已弃用)
已弃用。这种类型的身份验证将函数配置为在客户端应用程序调用函数时登录的现有应用程序用户的上下文中运行。如果从另一个函数调用该函数,则它将继承该函数的执行用户。
记录
这种类型的身份验证将函数配置为以系统用户身份运行,该用户对MongoDB 增删改查和聚合 API 具有完全访问权限,并且不受任何规则、角色或权限的影响。
用户ID (已弃用)
已弃用。这种类型的身份验证将函数配置为始终以特定应用程序用户身份运行。
脚本
这种类型的身份验证将函数配置为根据您定义的自定义函数的结果确定的特定应用程序用户运行。该函数必须返回特定用户的id字符串,或者可以通过返回{ "runAsSystem": true }来指定系统用户。
4

默认, Atlas在每次执行函数的日志条目中包含函数收到的参数。

要防止Atlas记录参数,请禁用Log Function Arguments

5

您可以通过定义Can Evaluate表达式,根据每个请求的内容动态授权请求。每当调用函数时, Atlas都会对表达式求值。如果未指定表达式, Atlas会自动授权所有经过身份验证的传入请求。

表达式可以扩展标准表达式变量,包括%%request%%user扩展。

函数的“可以评估用户界面中输入的JSON表达式”
点击放大
6

默认,您可以从客户端应用程序调用函数,也可以调用同一应用程序中的其他函数。您可以通过将Private设置为true来阻止客户端应用程序查看或调用函数。

您仍然可以从表达式和其他函数(包括传入的 webhook 和触发器)中调用私有函数。

用户界面中的私有函数切换
点击放大
7

创建并配置新函数后,您可以写入在调用函数时运行的JavaScript代码。

您可以使用函数编辑器直接在Atlas用户界面中写入代码。

  1. Create Function页面中,单击Function Editor标签页。

  2. 将JavaScript代码添加到函数。代码至少必须将函数分配给exports ,如以下示例:

    exports = function() {
    return "Hello, world!";
    };

    注意

    您可以在函数中使用大多数现代 (ES 6 +) JavaScript功能,包括异步/等待、解构和模板字面量。

8

单击Save 。保存函数后,您可以立即开始使用。

1

使用MongoDB Atlas Administration API密钥登录App Services CLI:

appservices login --api-key="<API KEY>" --private-api-key="<PRIVATE KEY>"
2

运行以下命令以获取配置文件的本地副本:

appservices pull --remote=<App ID>

默认,该命令会将文件提取到当前工作目录中。您可以使用可选的--local标志指定目录路径。

3

Atlas Function运行标准 ES 6 + 您从单个文件导出的JavaScript函数。

  1. functions目录或子目录中创建.js文件。

    文件名必须与函数名称匹配。在文件名中使用斜线表示子目录路径。

touch functions/<FunctionName>.js

提示

您可以在functions目录中的嵌套文件夹内定义函数。在函数名称中使用斜杠来指示其目录路径。示例,名为utils/add的函数映射到functions/utils/add.js

  1. 在创建的文件中写入函数源代码。

示例,以下函数hello.js会为提供的名称返回问候语:

functions/hello.js
exports = async function hello(...args) {
// Write your function logic here! You can...
// Import dependencies
const assert = require("assert")
assert(typeof args[0] === "string")
// Use ES6+ syntax
const sayHello = (name = "world") => {
console.log(`Hello, ${name}.`)
}
// Return values back to clients or other functions
return sayHello(args[0])
}

注意

您可以在函数中使用大多数现代 (ES 6 +) JavaScript功能,包括异步/等待、解构和模板字面量。

4

在本地应用程序的functions目录中,打开config.json文件并将新函数的配置对象添加到大量中。

该对象必须具有以下形式:

{
"name": "<Function Name>",
"private": <Boolean>,
"can_evaluate": { <JSON Expression> },
"disable_arg_logs": <Boolean>,
"run_as_system": <Boolean>,
"run_as_user_id": "<App Services User ID>",
"run_as_user_id_script_source": "<Function Source Code>"
}
  1. 配置用户身份验证:

    Atlas中的函数始终在特定应用程序用户的上下文中执行,或作为绕过规则的系统用户执行。要配置函数的执行用户,请指定Atlas应使用的身份验证类型。

    注意

    数据库函数和定时触发器始终在系统用户上下文中执行。

    • 系统用户:要以系统用户身份执行函数,请使用以下配置:

      系统用户配置
      {
      "run_as_system": true,
      "run_as_user_id": "",
      "run_as_user_id_script_source": ""
      }
    • 脚本:要以从另一个函数返回的用户身份执行该函数,请使用以下配置:

      脚本配置
      {
      "run_as_system": false,
      "run_as_user_id": "",
      "run_as_user_id_script_source": "<Function Source Code>"
      }
    • 用户(已弃用) :要以特定用户身份执行函数,请使用以下配置:

      用户ID配置(已弃用)
      {
      "run_as_system": false,
      "run_as_user_id": "<App Services User Id>",
      "run_as_user_id_script_source": ""
      }
  2. 配置函数日志:

    要在每次执行函数的日志条目中包含函数收到的参数,请将disable_arg_logs设立为false

  3. 指定授权表达式:

    您可以通过定义Can Evaluate表达式,根据每个请求的内容动态授权请求。每当调用函数时, Atlas都会对表达式求值。如果未指定表达式, Atlas会自动授权所有经过身份验证的传入请求。

    表达式可以扩展标准表达式变量,包括%%request%%user扩展。

    示例,以下表达式仅在发件人的IP解决未包含在指定地址列表中时才授权传入请求:

    授权表达式示例
    {
    "%%request.remoteIPAddress": {
    "$nin": [
    "248.88.57.58",
    "19.241.23.116",
    "147.64.232.1"
    ]
    }
    }
  4. 配置隐私级别:

    要防止客户端应用程序查看或调用函数,请将private设立为true

5

推送函数配置和源代码,将其部署到您的应用。您可以立即开始使用该功能。

运行以下命令以部署更改:

appservices push

您可以从另一个函数或使用App Services CLI调用一个函数。

本部分中的示例演示如何调用名为sum的简单函数,该函数接受两个参数、将它们相加并返回结果:

functions/sum.js
// sum: adds two numbers
exports = function sum(a, b) {
return a + b;
};

您可以通过context.functions接口从另一个函数调用一个函数,该接口可在任何函数中用作全局变量。被调用函数在与调用它的函数相同的上下文中运行。

// difference: subtracts b from a using the sum function
exports = function difference(a, b) {
return context.functions.execute("sum", a, -1 * b);
};

您可以使用function 运行命令通过App Services CLI调用函数。该命令以EJSON形式返回函数结果以及所有日志或错误消息。

appservices function run \
--name=sum \
--args=1 --args=2

默认,函数在系统上下文中运行。要在特定用户的上下文中调用函数,请在--user参数中包含其用户ID 。

appservices function run \
--name=sum \
--args=1 --args=2 \
--user=61a50d82532cbd0de95c7c89
  • 每个请求的函数运行时间上限为300秒,之后函数将超时并失败。

  • 函数可能随时使用高达350MB 的内存。

  • 函数不能超过 1000 次异步操作。

  • 函数支持最常用的 ES6+ 功能和 Node.js 内置模块,但不支持某些不常见或不适合无服务器工作负载的功能。有关详情,请参阅 JavaScript 支持。

  • 函数可以使用25 网络 打开最多 个套接字 内置模块。

  • 传入请求的最大大小限制为18 MB。此限制适用于传递给函数的所有参数的总大小。

后退

将触发器事件发送到 AWS EventBridge