最佳实践

API 网关触发器概述

最近更新时间:2021-07-27 17:36:16

您可以通过编写 SCF 云函数来实现 Web 后端服务,并通过 API 网关对外提供服务。API 网关会将请求内容以参数形式传递给函数,并将函数返回作为响应返回给请求方。

注意:

API 网关触发器同时支持事件函数与 Web 函数触发,本文仅介绍事件函数触发的请求方式,Web 函数触发请参考 Web 函数触发器管理

API 网关触发器具有以下特点:

  • Push 模型
    API 网关在接受到 API 请求后,如果 API 在网关上的后端配置了对接云函数,该函数将会被触发运行。同时 API 网关会将 API 请求的相关信息以 event 入参的形式发送给被触发的函数。API 请求的相关信息包含了例如具体接受到请求的服务和 API 规则、请求的实际路径、方法、请求的 path、header、query 等内容。
  • 同步调用
    API 网关以同步调用的方式来调用函数,会在 API 网关中配置的超时时间未到前等待函数返回。有关调用类型的更多信息,请参阅 调用类型

API 网关触发器配置

API 网关触发器分别支持在 云函数控制台 或在 API 网关控制台 中进行配置。

云函数控制台中,支持在触发方式中添加 API 网关触发器。支持选取已有 API 服务或新建 API 服务。支持请求方法(目前支持 ANY、GET、HEAD、POST、PUT、DELETE 六种方法的请求)、发布环境(测试、预发布及发布环境)及鉴权方式(API 网关密钥对)的定义。

API 网关触发器绑定限制

API 网关中,一条 API 规则仅能绑定一个云函数,但一个云函数可以被多个 API 规则绑定为后端。您可以在 API 网关控制台 创建一个包含不同路径的 API 并将后端指向同一个函数。相同路径、相同请求方法及不同发布环境的 API 被视为同一个 API,无法重复绑定。

目前 API 网关触发器仅支持同地域云函数绑定,例如广州地区创建的云函数,仅支持被广州地区创建的 API 服务中规则所绑定和触发。如果您想要使用特定地域的 API 网关配置来触发云函数,可以通过在对应地域下创建函数来实现。

请求与响应

针对 API 网关发送到云函数的请求处理方式,和云函数响应给 API 网关的返回值处理方式,称为请求方法和响应方法。请求方法和响应方法规划和实现的分别有透传方式和集成方式。

集成请求与透传请求

集成请求,是指 API 网关会将 HTTP 请求内容,转换为请求数据结构;请求数据结构作为函数的 event 输入参数,传递给函数并进行处理。具体请求数据结构说明见如下。

透传请求,是指 API 网关会将 HTTP 请求的 body 内容作为函数的 event 输入参数传递给函数,透传请求目前还处于规划过程中。对于透传请求,要求 HTTP 请求的 body 内容为 JSON 数据结构内容。

注意:

  • 当前 API 网关触发器触发云函数时,全部使用集成请求。
  • 当您需要将图片或文件通过 API 网关传入云函数时,需要将图片或文件进行 Base64 编码。如果上传的文件在 Base64 编码后的大小超过6MB,建议您通过客户端先将文件上传至 COS,再将 Object 地址传递给云函数,由云函数从 COS 拉取文件,以完成大文件的上传。

API 网关触发器的集成请求事件消息结构

在 API 网关触发器接收到请求时,会将类似以下 JSON 格式的事件数据发送给绑定的云函数。

{
 "requestContext": {
   "serviceId": "service-f94sy04v",
   "path": "/test/{path}",
   "httpMethod": "POST",
   "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
   "identity": {
     "secretId": "abdcdxxxxxxxsdfs"
   },
   "sourceIp": "10.0.2.14",
   "stage": "release"
 },
 "headers": {
   "accept-Language": "en-US,en,cn",
   "accept": "text/html,application/xml,application/json",
   "host": "service-3ei3tii4-251000691.ap-guangzhou.apigateway.myqloud.com",
   "user-Agent": "User Agent String"
 },
 "body": "{\"test\":\"body\"}",
 "pathParameters": {
   "path": "value"
 },
 "queryStringParameters": {
   "foo": "bar"
 },
 "headerParameters":{
   "Refer": "10.0.2.14"
 },
 "stageVariables": {
   "stage": "release"
 },
 "path": "/test/value",
 "queryString": {
   "foo" : "bar",
   "bob" : "alice"
 },
 "httpMethod": "POST"
}

数据结构内容详细说明如下:

结构名 内容
requestContext 请求来源的 API 网关的配置信息、请求标识、认证信息、来源信息。其中:
  • serviceId,path,httpMethod 指向 API 网关的服务 ID、API 的路径和方法。
  • stage 指向请求来源 API 所在的环境。
  • requestId 标识当前这次请求的唯一 ID。
  • identity 标识用户的认证方法和认证的信息。
  • sourceIp 标识请求来源 IP。
path 记录实际请求的完整 Path 信息。
httpMethod 记录实际请求的 HTTP 方法。
queryString 记录实际请求的完整 Query 内容。
body 记录实际请求转换为 String 字符串后的内容。
headers 记录实际请求的完整 Header 内容。
pathParameters 记录在 API 网关中配置过的 Path 参数以及实际取值。
queryStringParameters 记录在 API 网关中配置过的 Query 参数以及实际取值。
headerParameters 记录在 API 网关中配置过的 Header 参数以及实际取值。
注意:

  • 在 API 网关迭代过程中, requestContext 内的内容可能会增加更多。目前会保证数据结构内容仅增加,不删除,不对已有结构进行破坏。
  • 实际请求时的参数数据可能会在多个位置出现,可根据业务需求选择使用。

集成响应与透传响应

集成响应,是指 API 网关会将云函数的返回内容进行解析,并根据解析内容构造 HTTP 响应。通过使用集成响应,可以通过代码自主控制响应的状态码、headers、body 内容,可以实现自定义格式的内容响应,例如响应 XML、HTML、JSON 甚至 JS 内容。在使用集成响应时,需要按照 API 网关触发器的集成响应返回数据结构,才可以被 API 网关成功解析,否则会出现 {"errno":403,"error":"Invalid scf response format. please check your scf response format."} 错误信息。

透传响应,是指 API 网关将云函数的返回内容直接传递给 API 请求方。通常这种响应的数据格式直接确定为 JSON 格式,状态码根据函数执行的状态定义,函数执行成功即为 200 状态码。通过透传响应,用户可以自行获取到 JSON 格式后在调用位置解析结构,获取结构内的内容。

注意:

  • 如果当前通过 API 网关控制台配置的 API 网关触发器,处理响应的方式默认为透传响应。如需开启集成响应,请在 API 配置中的后端配置位置,勾选启用集成响应,并在代码中按如下说明的数据结构返回内容。
  • 如果当前通过云函数控制台配置的 API 网关触发器,默认已开启集成响应功能,请注意返回数据的格式。

API 网关触发器的集成响应返回数据结构

在 API 网关设置为集成响应时,需要将包含以下 JSON 格式的数据结构返回给 API 网关。

{
   "isBase64Encoded": false,
   "statusCode": 200,
   "headers": {"Content-Type":"text/html"},
   "body": "<html><body><h1>Heading</h1><p>Paragraph.</p></body></html>"
}

数据结构内容详细说明如下:

结构名 内容
isBase64Encoded 指明 body 内的内容是否为 Base64 编码后的二进制内容,取值需要为 JSON 格式的 true 或 false。
statusCode HTTP 返回的状态码,取值需要为 Integer 值。
headers HTTP 返回的头部内容,取值需要为多个 key-value 对象,或 key:[value,value] 对象。其中 key、value 均为字符串。headers 请求头暂不支持 Location key。
body HTTP 返回的 body 内容。

在需要返回 key 相同的多个 headers 时,可以使用字符串数组的方式描述不同 value,例如:

{
   "isBase64Encoded": false,
   "statusCode": 200,
   "headers": {"Content-Type":"text/html","Key":["value1","value2","value3"]},
   "body": "<html><body><h1>Heading</h1><p>Paragraph.</p></body></html>"
}
目录