自定义 HTTPS 端点
您可定义自定义 HTTPS 端点来创建特定于应用的 API 路由或与外部服务集成的 Webhook。自定义端点使用您编写的无服务器函数来处理针对特定 URL 和 HTTP 方法的传入请求。
端点使用标准的加密 HTTPS 请求,这意味着您无需安装任何数据库驱动程序或偏好明确的库即可调用它们。相反,您可以从任何 HTTP 客户端发送如下请求:
curl -s "https://data.mongodb-api.com/app/myapp-abcde/endpoint/hello" \ -X POST \ -H "Accept: application/json" \ -H "apiKey: TpqAKQgvhZE4r6AOzpVydJ9a3tB1BLMrgDzLlBLbihKNDzSJWTAHMVbsMoIOpnM6" \ -d '{ "name": "Casey" }'
端点的结构
端点处理发送到特定 URL 的一个或多个 HTTP 方法。
基本 URL
应用中的端点共享一个基本 URL。该 URL 使用 App ID 来专门指向您的应用。
全局部署的应用程序采用以下格式:
https://data.mongodb-api.com/app/<App ID>/endpoint
本地部署应用中的终结点使用特定于该应用的部署地区的基本 URL(例如 us-east-1
)
https://<Region>.aws.data.mongodb-api.com/app/<App ID>/endpoint
端点路由
每个 HTTPS 端点都有一个用作端点名称的路由。端点的路由是任意的,并且特定于您的应用。但是,它出现在端点 URL 路径中,因此应代表路由执行的操作。
路由名称必须以正斜杠 (/
) 开头,可包含其他正斜杠来表示嵌套路径。
/my/nested/route
您可以通过将端点的路由附加到应用的基本 URL 并发送 HTTP 请求来调用该端点。
https://data.mongodb-api.com/app/<App ID>/endpoint/my/nested/route
HTTP 方法
应用程序中的每个端点都会处理一个或多个 HTTP 方法 对于给定的路线。例如,您可能有一个路由,它可接受用于创建新资源的POST
GET
请求。
您可以定义多个自定义端点,这些端点为同一路由提供服务,但处理不同的请求方法。或者,您可以为处理所有方法的路由定义单个端点。
自定义端点支持以下标准 HTTP 方法:
创建自定义 HTTPS 端点
您可以通过 App Services UI 或使用 App Services CLI 部署配置文件,来配置应用的 Data API:
身份验证
自定义端点在特定用户的上下文中运行,这允许您的应用强制执行规则并验证每个请求的文档模式。
默认情况下,端点使用“应用程序身份验证”,要求每次请求都包含一个应用程序用户的凭据,如 API 密钥或 JWT。您还可以配置其他自定义身份验证方案,以满足应用程序的需求。
有关如何对请求进行身份验证的示例,请参阅对 Data API 请求进行身份验证。
提示
默认情况下,您在用户界面中创建的新端点使用系统身份验证。
授权
端点可以要求已通过身份验证的用户在请求中提供其他授权信息。您可以通过配置端点函数来为每个自定义端点定义授权方案。
端点本身支持一组内置授权方案,这些方案使用密钥字符串来证明请求已获授权。您还可以定义自定义授权方案,可以将其与内置方案一起使用或代替内置方案。
要了解如何为特定函数配置授权,请参阅定义函数。
内置授权模式
端点支持以下内置授权方案:
自定义授权模式
您可以定义自定义授权表达式,以确定是否允许运行传入的已验证请求。该表达式针对每个请求进行计算,并且其计算结果必须为 true
才能允许请求。如果表达式的计算结果为 false
,则请求不会获得授权并出现错误,以失败告终。未通过授权的请求不计入应用的计费使用量。
授权表达式可使用 %%user
等变量,根据调用用户的数据进行授权,或使用 %%request
等变量,根据每次传入请求的具体情况做出决定。
要定义自定义授权方案,请在端点函数的配置中指定以下表达式:
[ { ..., "can_evaluate": { "%%request.requestHeaders.x-secret-key": "my-secret" } } ]
写入端点函数
每个自定义端点都与一个函数相关联,该函数在端点接收到传入请求时运行。在该函数中,您可以从 npm 导入库,连接到已链接的 MongoDB Atlas 集群,调用其他无服务器函数。
要在 App Services 用户界面中创建端点时定义新函数,请导航至 Function部分,然后从下拉列表中选择+ New Function 。
根据工作流程,您还可以定义和编辑端点处理程序函数:
在 App Services UI 的 Functions 页面。
在使用 App Services CLI 的应用程序的
functions
目录中。
端点函数总是接收两个参数:
有关示例函数以及示例请求和响应,请参阅示例。
访问请求数据
自定义端点 Request
对象表示调用端点的 HTTP 请求。您可以访问传入请求的标头、查询参数和正文数据。
{ "headers": { "<Header>": ["<Header Value>"] }, "query": { "<Query Parameter>": "<Parameter Value>" }, "body": <BSON.Binary> }
字段 | 说明 | |||||
---|---|---|---|---|---|---|
query | 一个对象,其中每个字段均会将 URL 查询参数映射到其值。如果在查询字符串中多次使用某个密钥,则在此对象中仅表示第一次出现的情况。要使用完整的查询字符串,请使用 context.request.rawQueryString。 例子以下
| |||||
headers | 一个对象,其中每个字段将请求标头名称映射到一个或多个值的数组。 例子
| |||||
body | 包含请求正文的 BSON.Binary 对象。如果请求不含正文,则此值为 要访问请求正文中的数据,需要序列化以下二进制文件:
|
返回 HTTPS 响应
自定义端点 Response
Realm 对象允许你配置发送回调用方的 HTTPS 响应。你可以制定状态代码、自定义标头以及在响应正文中包含数据。
方法 | 说明 | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
setStatusCode(code) - code: number | 设置 HTTP 响应 状态代码。 例子
| |||||||||
setBody(body) - body: string | BSON.Binary | 设置 HTTP 响应 正文。 如果 例子
| |||||||||
setHeader(name, value) - name: string - value: string | 设置 HTTP 响应 标头 例子
| |||||||||
addHeader(name, value) - name: string - value: string | 设置 HTTP 响应 标头 例子
|
例子
考虑一个端点函数,它解析传入的 POST
请求的正文,将解析后的正文存储在 MongoDB 集合中,然后响应调用方:
exports = async function MyCustomEndpoint(request, response) { try { // 1. Parse data from the incoming request if (request.body === undefined) { throw new Error(`Request body was not defined.`); } const body = JSON.parse(request.body.text()); // 2. Handle the request const { insertedId } = await context.services .get("mongodb-atlas") .db("myDb") .collection("myCollection") .insertOne({ date: new Date(), requestBody: body }); // 3. Configure the response response.setStatusCode(201); // tip: You can also use EJSON.stringify instead of JSON.stringify. response.setBody( JSON.stringify({ insertedId, message: "Successfully saved the request body", }) ); } catch (error) { response.setStatusCode(400); response.setBody(error.message); } };
此函数接收以下 POST
请求:
curl -s "https://data.mongodb-api.com/app/myapp-abcde/endpoint/custom" \ -X POST \ -H "Accept: application/json" \ -H "apiKey: TpqAKQgvhZE4r6AOzpVydJ9a3tB1BLMrgDzLlBLbihKNDzSJWTAHMVbsMoIOpnM6" \ -d '{ "type": "event", "date": "2024-01-01T00:00:00.000Z", "name": "New Year Begins", "comment": "Happy New Year!" }'
{ "message": "Successfully saved the request body", "insertedId": "639a521bbdec9b85ba94014b" }
该函数验证传入请求的正文已定义后,会将解析后的正文作为新文档存储在名为 myCollection
的集合中。生成的输出显示配置的响应,其中包括自定义消息和 insertedId
。
调用自定义端点
您可从任意标准 HTTPS 客户端调用自定义端点。
curl -s "https://data.mongodb-api.com/app/myapp-abcde/endpoint/hello" \ -X POST \ -H "Accept: application/json" \ -H "apiKey: TpqAKQgvhZE4r6AOzpVydJ9a3tB1BLMrgDzLlBLbihKNDzSJWTAHMVbsMoIOpnM6" \ -d '{ "name": "Casey" }'
发出请求时需要使用 HTTP/1.1 或更高版本。
选择响应数据格式
请求可以包含 Accept
标头,以请求响应正文的特定数据格式(JSON 或 EJSON)。如果请求不包含有效的 Accept
标头,则响应将使用端点配置中指定的默认数据格式。
验证请求
如果端点配置为使用应用程序身份验证,则必须在每个请求中包含有效的用户访问令牌或登录档案。
一般来说,与凭证标头相比,使用访问令牌进行持有者身份验证具有更高的吞吐量且更安全。尽可能使用访问令牌而不是凭证标头。该令牌允许您运行多个请求,而无需重新验证用户身份。它还允许您从实施 CORS 的 Web 浏览器发送请求。
要使用访问令牌,请先通过 App Services 身份验证提供者来对用户进行身份验证。然后,获取从 App Services 返回的访问令牌,并使用持有者令牌方案将其包含在请求的“授权”标头中。有关如何获取和使用访问令牌的详情,请参阅持有者令牌身份验证。
curl -X GET \ -H 'Authorization: Bearer <AccessToken>' \ -H 'Content-Type: application/json' \ https://data.mongodb-api.com/app/myapp-abcde/endpoint/hello
或者也可以在请求标头中包含用户的有效登录档案。
重要
请勿在面向用户的客户端中使用 API 密钥
如果您从浏览器或其他面向用户的客户端应用程序进行身份验证,请避免使用 API 密钥登录。请改用其他接受用户提供的档案的身份验证提供者。切勿在本地存储 API 密钥或其他敏感档案。
授权请求
根据端点配置,您的请求可能需要包含其他授权信息。