调用第三方 API - Amazon Step Functions
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

调用第三方 API

HTTP 任务是一种 Task 状态,可让您在工作流中调用任何公共第三方 API,例如 Salesforce 和 Stripe。要调用第三方 API,请配合使用 Task 状态与 arn:aws:states:::http:invoke 资源。然后,提供 API 端点配置详细信息,例如 API URL、您要使用的方法和身份验证详细信息。

如果您使用 Workflow Studio 构建包含 HTTP 任务的状态机,则 Workflow Studio 会自动为 HTTP 任务生成一个带 IAM 策略的执行角色。有关更多信息,请参阅在 Workflow Studio 中测试 HTTP 任务的角色

HTTP 任务定义

ASL 定义表示具有 http:invoke 资源的 HTTP 任务。以下 HTTP 任务定义调用了一个会返回所有客户列表的 Stripe API。

"Call third-party API": { "Type": "Task", "Resource": "arn:aws:states:::http:invoke", "Parameters": { "ApiEndpoint": "https://api.stripe.com/v1/customers", "Authentication": { "ConnectionArn": "arn:aws:events:us-east-2:123456789012:connection/Stripe/81210c42-8af1-456b-9c4a-6ff02fc664ac" }, "Method": "GET" }, "End": true }

HTTP 任务字段

HTTP 任务的定义中包括以下字段。

Resource(必填)

要指定任务类型,请在 Resource 字段中提供其 ARN。对于 HTTP 任务,您可以按如下方式指定 Resource 字段。

"Resource": "arn:aws:states:::http:invoke"
Parameters(必填)

包含 ApiEndpointMethodConnectionArn 字段,这些字段提供有关您要调用的第三方 API 的信息。Parameters 还包含可选字段,例如 HeadersQueryParameters

您可以像在Parameters字段Parameters中一样指定静态 JSON 和JsonPath语法的组合。有关更多信息,请参阅将参数传递给服务 API

ApiEndpoint(必填)

指定您要调用的第三方 API 的 URL。要将查询参数附加到 URL,请使用 QueryParameters 字段。以下示例展示了如何调用 Stripe API 来获取所有客户的列表。

"ApiEndpoint":"https://api.stripe.com/v1/customers"

您也可以使用JsonPath语法指定参考路径,以选择包含第三方 API 网址的 JSON 节点。例如,假设您想使用特定客户 ID 调用 Stripe 的某个 API。想象一下,您已提供以下状态输入。

{ "customer_id": "1234567890", "name": "John Doe" }

要使用 Stripe API 检索该客户 ID 的详细信息,请指定 ApiEndpoint,如以下示例中所示。此示例使用了内置函数和参考路径。

"ApiEndpoint.$":"States.Format('https://api.stripe.com/v1/customers/{}', $.customer_id)"

在运行时,Step Functions 解析 ApiEndpoint 的值,如下所示。

https://api.stripe.com/v1/customers/1234567890
Method(必填)

指定要用于调用第三方 API 的 HTTP 方法。您可以在 HTTP 任务中指定以下方法之一:GET、POST、PUT、DELETE、PATCH、OPTIONS 或 HEAD。

例如,要使用 GET 方法,请按如下方式指定 Method 字段。

"Method": "GET"

您也可以在运行时使用参考路径来指定方法。例如,"Method.$": "$.myHTTPMethod"

Authentication(必填)

包含指定如何对第三方 API 调用进行身份验证的 ConnectionArn 字段。Step Functions 支持使用 Amazon EventBridge 的连接资源对指定 ApiEndpoint 进行身份验证。

ConnectionArn(必填)

指定 EventBridge 连接 ARN。

HTTP 任务需要EventBridge 连接,该连接可以安全地管理 API 提供商的身份验证凭证。连接会指定用于授权第三方 API 的授权类型和凭证。使用连接可以帮助您避免将密钥(例如 API 密钥)硬编码到状态机定义中。在连接中,您还可以指定 HeadersQueryParametersRequestBody 参数。

创建 EventBridge 连接时,您需要提供身份验证详细信息。有关如何对 HTTP 任务进行身份验证的更多信息,请参阅HTTP 任务的身份验证

以下示例说明了如何在 HTTP 任务定义中指定 Authentication 字段。

"Authentication": { "ConnectionArn": "arn:aws:events:us-east-2:123456789012:connection/Stripe/81210c42-8af1-456b-9c4a-6ff02fc664ac" }
Headers(可选)

为 API 端点提供额外的上下文和元数据。您可以将标头指定为字符串或 JSON 数组。

您可以在 EventBridge 连接以及 HTTP 任务的 Headers 字段中指定标头。建议您不要在 Headers 字段中包含 API 提供程序的身份验证详细信息。建议您将这些详细信息包含在 EventBridge 连接中。

Step Functions 会将您在 EventBridge 连接中指定的标头添加到您在 HTTP 任务定义中指定的标头。如果定义和连接中存在相同的标头键,则 Step Functions 会使用 EventBridge 连接中为这些标头指定的相应值。有关 Step Functions 如何执行数据合并的更多信息,请参阅合并 EventBridge 连接和 HTTP 任务定义数据

以下示例指定了将包含在第三方 API 调用中的标头:content-type

"Headers": { "content-type": "application/json" }

您也可以在运行时使用参考路径来指定标头。例如,"Headers.$": "$.myHTTPHeaders"

Step Functions 可设置 User-AgentRangeHost 标头。Step Functions 会根据您要调用的 API 设置 Host 标头的值。以下是这些标头的一个示例。

User-Agent: Amazon|StepFunctions|HttpInvoke|us-east-1, Range: bytes=0-262144, Host: api.stripe.com

您不能在 HTTP 任务定义中使用以下标头。如果您使用这些标头,HTTP 任务将失败并显示 States.Runtime 错误。

  • A-IM

  • Accept-Charset

  • Accept-Datetime

  • Accept-Encoding

  • Cache-Control

  • Connection

  • Content-Encoding

  • Content-MD5

  • Date

  • Expect

  • Forwarded

  • From

  • Host

  • HTTP2-Settings

  • If-Match

  • If-Modified-Since

  • If-None-Match

  • If-Range

  • If-Unmodified-Since

  • Max-Forwards

  • Origin

  • Pragma

  • Proxy-Authorization

  • Referer

  • Server

  • TE

  • Trailer

  • Transfer-Encoding

  • Upgrade

  • Via

  • Warning

  • x-forwarded-*

  • x-amz-*

  • x-amzn-*

QueryParameters(可选)

在 API URL 的末尾插入键值对。您可以将查询参数指定为字符串、JSON 数组或 JSON 对象。当调用第三方 API 时,Step Functions 会自动对查询参数进行 URL 编码。

例如,假设您想调用 Stripe API 来搜索使用美元 (USD) 进行交易的客户。想象一下,您已提供以下 QueryParameters 作为状态输入。

"QueryParameters": { "currency": "usd" }

在运行时,Step Functions 会将 QueryParameters 附加到 API URL,如下所示。

https://api.stripe.com/v1/customers/search?currency=usd

您也可以在运行时使用参考路径来指定查询参数。例如,"QueryParameters.$": "$.myQueryParameters"

如果您在 EventBridge 连接中指定了查询参数,则 Step Functions 会将这些查询参数添加到您在 HTTP 任务定义中指定的查询参数。如果定义和连接中存在相同的查询参数键,则 Step Functions 会使用 EventBridge 连接中为这些标头指定的相应值。有关 Step Functions 如何执行数据合并的更多信息,请参阅合并 EventBridge 连接和 HTTP 任务定义数据

Transform(可选)

包含 RequestBodyEncodingRequestEncodingOptions 字段。默认情况下,Step Functions 会将请求正文作为 JSON 数据发送到 API 端点。

如果您的 API 提供程序接受 form-urlencoded 请求正文,请使用 Transform 字段为请求正文指定 URL 编码。您还必须将 content-type 标头指定为 application/x-www-form-urlencoded。Step Functions 然后会自动对请求正文进行 URL 编码。

RequestBodyEncoding

指定请求正文的 URL 编码。您可以指定以下值之一:NONEURL_ENCODED

  • NONE:HTTP 请求正文将是 RequestBody 字段的序列化 JSON。这是默认值。

  • URL_ENCODED:HTTP 请求正文将是 RequestBody 字段的 URL 编码表单数据。

RequestEncodingOptions

用于确定在您将 RequestBodyEncoding 设置为 URL_ENCODED 的情况下,要为请求正文中的数组使用的编码选项。

Step Functions 支持以下数组编码选项。有关这些选项的更多信息及其示例,请参阅在请求正文上应用 URL 编码

  • INDICES:使用数组元素的索引值对数组进行编码。Step Functions 默认使用此编码选项。

  • REPEAT:针对数组中的每个项重复使用一个键。

  • COMMAS:将键中的所有值编码为以逗号分隔的值列表。

  • BRACKETS:针对数组中的每个项重复使用一个键,并为该键附加一个方括号 [],以表示它是一个数组。

以下示例为请求正文数据设置了 URL 编码。它还指定在请求正文中为数组使用 COMMAS 编码选项。

"Transform": { "RequestBodyEncoding": "URL_ENCODED", "RequestEncodingOptions": { "ArrayFormat": "COMMAS" } }
RequestBody(可选)

接受您在状态输入中提供的 JSON 数据。在中RequestBody,您可以指定静态 JSON 和JsonPath语法的组合。例如,假设您提供以下状态输入:

{ "CardNumber": "1234567890", "ExpiryDate": "09/25" }

要在运行时在请求正文中使用 CardNumberExpiryDate 的这些值,您可以在请求正文中指定以下 JSON 数据。

"RequestBody": { "Card": { "Number.$": "$.CardNumber", "Expiry.$": "$.ExpiryDate", "Name": "John Doe", "Address": "123 Any Street, Any Town, USA" } }

如果您要调用的第三方 API 需要 form-urlencoded 请求正文,则您必须为请求正文数据指定 URL 编码。有关更多信息,请参阅在请求正文上应用 URL 编码

HTTP 任务的身份验证

HTTP 任务需要EventBridge 连接,该连接可以安全地管理 API 提供商的身份验证凭证。连接会指定用于授权第三方 API 的授权类型和凭证。使用连接可以帮助您避免将密钥(例如 API 密钥)硬编码到状态机定义中。 EventBridge 连接支持基本、OAuth 和 API 密钥授权方案。

创建 EventBridge 连接时,您需要提供身份验证详细信息。您还可以包含授权 API 所需的标头、正文和查询参数。您必须在调用第三方 API 的任何 HTTP 任务中包含连接 ARN。

当您创建连接并添加授权参数时, EventBridge 会在中创建密钥 Amazon Secrets Manager。在此密钥中,以加密形式 EventBridge 存储连接和授权参数。要成功创建或更新连接,必须使用有权使用 S Amazon Web Services 账户 ecrets Manager 的。有关状态机访问 EventBridge 连接所需的IAM权限的更多信息,请参阅运行 HTTP 任务的 IAM 权限

下图显示了 Step Functions 如何使用 EventBridge 连接处理第三方 API 调用的身份验证。


                Process Step Functions 使用 EventBridge 连接来管理第三方 API 提供程序的身份验证凭证。EventBridge 会在 Secrets Manager 中创建密钥,以加密形式存储连接和授权参数。

合并 EventBridge 连接和 HTTP 任务定义数据

调用 HTTP 任务时,您可以在 EventBridge 连接和 HTTP 任务定义中指定数据。此数据包括 HeadersQueryParametersRequestBody 参数。在调用第三方 API 之前,Step Functions 会将请求正文与连接正文参数合并,除非您的请求正文为字符串且连接正文参数非空。在这种情况下,HTTP 任务将失败并显示 States.Runtime 错误。

如果 HTTP 任务定义和 EventBridge 连接中指定了任何重复的键,则 Step Functions 会用连接中的值覆盖 HTTP 任务中的值。

以下列表说明了在调用第三方 API 之前 Step Functions 如何合并数据:

  • 标头:Step Functions 会将您在连接中指定的任何标头添加到 HTTP 任务 Headers 字段中的标头。如果标头键之间存在冲突,Step Functions 会使用连接中为这些标头指定的值。例如,如果您在 HTTP 任务定义和 EventBridge 连接中都指定了 content-type 标头,则 Step Functions 会使用连接中指定的 content-type 标头值。

  • 查询参数:Step Functions 会将您在连接中指定的任何查询参数添加到 HTTP 任务 QueryParameters 字段中的查询参数。如果查询参数键之间存在冲突,Step Functions 会使用连接中为这些查询参数指定的值。例如,如果您在 HTTP 任务定义和 EventBridge 连接中都指定了 maxItems 查询参数,则 Step Functions 会使用连接中指定的 maxItems 查询参数值。

  • 主体参数

    • Step Functions 会将连接中指定的任何请求正文值添加到 HTTP 任务 RequestBody 字段中的请求正文。如果请求正文键之间存在冲突,Step Functions 会使用连接中为请求正文指定的值。例如,假设您在 HTTP 任务定义和 EventBridge 连接的 RequestBody 中都指定了 Mode 字段。Step Functions 会使用您在连接中指定的 Mode 字段值。

    • 如果您将请求正文指定为字符串而不是 JSON 对象,并且 EventBridge 连接还包含请求正文,则 Step Functions 无法合并在这两个位置指定的请求正文。它会使 HTTP 任务失败,并显示 States.Runtime 错误。

    在请求正文完成合并后,Step Functions 会应用所有转换并将请求正文序列化。

以下示例在 HTTP 任务和 EventBridge 连接中设置了 HeadersQueryParametersRequestBody 字段。

HTTP 任务定义

{ "Comment": "Data merging example for HTTP Task and EventBridge connection", "StartAt": "ListCustomers", "States": { "ListCustomers": { "Type": "Task", "Resource": "arn:aws:states:::http:invoke", "Parameters": { "Authentication": { "ConnectionArn": "arn:aws:events:us-east-1:123456789012:connection/Example/81210c42-8af1-456b-9c4a-6ff02fc664ac" }, "ApiEndpoint": "https:/example.com/path", "Method": "GET", "Headers": { "Request-Id": "my_request_id", "Header-Param": "state_machine_header_param" }, "RequestBody": { "Job": "Software Engineer", "Company": "AnyCompany", "BodyParam": "state_machine_body_param" }, "QueryParameters": { "QueryParam": "state_machine_query_param" } } } } }

EventBridge 连接

{ "AuthorizationType": "API_KEY", "AuthParameters": { "ApiKeyAuthParameters": { "ApiKeyName": "ApiKey", "ApiKeyValue": "key_value" }, "InvocationHttpParameters": { "BodyParameters": [ { "Key": "BodyParam", "Value": "connection_body_param" } ], "HeaderParameters": [ { "Key": "Header-Param", "Value": "connection_header_param" } ], "QueryStringParameters": [ { "Key": "QueryParam", "Value": "connection_query_param" } ] } } }

在此示例中,HTTP 任务和 EventBridge 连接中指定了重复的键。因此,Step Functions 用连接中的值覆盖 HTTP 任务中的值。以下代码段显示了 Step Functions 发送到第三方 API 的 HTTP 请求。

POST /path?QueryParam=connection_query_param HTTP/1.1 Apikey: key_value Content-Length: 79 Content-Type: application/json; charset=UTF-8 Header-Param: connection_header_param Host: example.com Range: bytes=0-262144 Request-Id: my_request_id User-Agent: Amazon|StepFunctions|HttpInvoke|us-east-1 {"Job":"Software Engineer","Company":"AnyCompany","BodyParam":"connection_body_param"}

在请求正文上应用 URL 编码

默认情况下,Step Functions 会将请求正文作为 JSON 数据发送到 API 端点。如果您的第三方 API 提供程序需要 form-urlencoded 请求正文,则您必须为请求正文指定 URL 编码。Step Functions 然后会根据您选择的 URL 编码选项自动对请求正文进行 URL 编码。

您可以使用 Transform 字段指定 URL 编码。此字段包含 RequestBodyEncoding 字段,后者用于指定您是否要为请求正文应用 URL 编码。当您指定 RequestBodyEncoding 字段时,Step Functions 会在调用第三方 API 之前,将您的 JSON 请求正文转换为 form-urlencoded 请求正文。您还必须将 content-type 标头指定为 application/x-www-form-urlencoded,因为接受 URL 编码数据的 API 需要 content-type 标头。

为对请求正文中的数组进行编码,Step Functions 提供以下数组编码选项。

  • INDICES:针对数组中的每个项重复使用一个键,并为该键附加一个方括号 [],以表示它是一个数组。此方括号包含数组元素的索引。添加索引可帮助您指定数组元素的顺序。Step Functions 默认使用此编码选项。

    例如,如果您的请求正文包含以下数组。

    {"array": ["a","b","c","d"]}

    Step Functions 会将此数组编码为以下字符串。

    array[0]=a&array[1]=b&array[2]=c&array[3]=d
  • REPEAT:针对数组中的每个项重复使用一个键。

    例如,如果您的请求正文包含以下数组。

    {"array": ["a","b","c","d"]}

    Step Functions 会将此数组编码为以下字符串。

    array=a&array=b&array=c&array=d
  • COMMAS:将键中的所有值编码为以逗号分隔的值列表。

    例如,如果您的请求正文包含以下数组。

    {"array": ["a","b","c","d"]}

    Step Functions 会将此数组编码为以下字符串。

    array=a,b,c,d
  • BRACKETS:针对数组中的每个项重复使用一个键,并为该键附加一个方括号 [],以表示它是一个数组。

    例如,如果您的请求正文包含以下数组。

    {"array": ["a","b","c","d"]}

    Step Functions 会将此数组编码为以下字符串。

    array[]=a&array[]=b&array[]=c&array[]=d

运行 HTTP 任务的 IAM 权限

您的状态机执行角色必须具有 states:InvokeHTTPEndpointevents:RetrieveConnectionCredentialssecretsmanager:GetSecretValuesecretsmanager:DescribeSecret 权限,HTTP 任务才能调用第三方 API。下面的 IAM 策略示例授予状态机角色调用 Stripe API 所需的最低权限。此 IAM 策略还向状态机角色授予访问特定 EventBridge 连接的权限,包括存储在 Secrets Manager 中的此连接的密钥。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "Statement1", "Effect": "Allow", "Action": "states:InvokeHTTPEndpoint", "Resource": "arn:aws:states:us-east-2:123456789012:stateMachine:myStateMachine", "Condition": { "StringEquals": { "states:HTTPMethod": "GET" }, "StringLike": { "states:HTTPEndpoint": "https://api.stripe.com/*" } } }, { "Sid": "Statement2", "Effect": "Allow", "Action": [ "events:RetrieveConnectionCredentials", ], "Resource": "arn:aws:events:us-east-2:123456789012:connection/oauth_connection/aeabd89e-d39c-4181-9486-9fe03e6f286a" }, { "Sid": "Statement3", "Effect": "Allow", "Action": [ "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret" ], "Resource": "arn:aws:secretsmanager:*:*:secret:events!connection/*" } ] }

HTTP 任务示例

以下状态机定义显示了包含 HeadersQueryParameters TransformRequestBody 参数的 HTTP 任务。该 HTTP 任务调用 Stripe API https://api.stripe.com/v1/invoices 来生成发票。该 HTTP 任务还使用 INDICES 编码选项为请求正文指定 URL 编码。

确保您已创建 EventBridge 连接。以下示例显示了使用基本授权类型创建的连接。

{ "Type": "BASIC", "AuthParameters": { "BasicAuthParameters": { "Password": "myPassword", "Username": "myUsername" }, } }

切记用特定资源信息替换斜体文本。

{ "Comment": "A state machine that uses HTTP Task", "StartAt": "CreateInvoiceAPI", "States": { "CreateInvoiceAPI": { "Type": "Task", "Resource": "arn:aws:states:::http:invoke", "Parameters": { "ApiEndpoint": "https://api.stripe.com/v1/invoices", "Method": "POST", "Authentication": { "ConnectionArn": ""arn:aws:events:us-east-2:123456789012:connection/Stripe/81210c42-8af1-456b-9c4a-6ff02fc664ac" }, "Headers": { "Content-Type": "application/x-www-form-urlencoded" }, "RequestBody": { "customer.$": "$.customer_id", "description": "Monthly subscription", "metadata": { "order_details": "monthly report data" } }, "Transform": { "RequestBodyEncoding": "URL_ENCODED", "RequestEncodingOptions": { "ArrayFormat": "INDICES" } } }, "Retry": [ { "ErrorEquals": [ "States.Http.StatusCode.429", "States.Http.StatusCode.503", "States.Http.StatusCode.504", "States.Http.StatusCode.502" ], "BackoffRate": 2, "IntervalSeconds": 1, "MaxAttempts": 3, "JitterStrategy": "FULL" } ], "Catch": [ { "ErrorEquals": [ "States.Http.StatusCode.404", "States.Http.StatusCode.400", "States.Http.StatusCode.401", "States.Http.StatusCode.409", "States.Http.StatusCode.500" ], "Comment": "Handle all non 200 ", "Next": "HandleInvoiceFailure" } ], "End": true } } }

要运行此状态机,请提供客户 ID 作为输入,如以下示例所示:

{ "customer_id": "1234567890" }

以下示例显示了 Step Functions 发送到 Stripe API 的 HTTP 请求。

POST /v1/invoices HTTP/1.1 Authorization: Basic <base64 of username and password> Content-Type: application/x-www-form-urlencoded Host: api.stripe.com Range: bytes=0-262144 Transfer-Encoding: chunked User-Agent: Amazon|StepFunctions|HttpInvoke|us-east-1 description=Monthly%20subscription&metadata%5Border_details%5D=monthly%20report%20data&customer=1234567890

测试 HTTP 任务

您可以通过控制台、软件开发工具包或使用TestState该 API Amazon CLI 来测试 HTTP 任务。以下过程介绍如何在Step Functions控制台中使用 TestState API。您可以迭代测试 API 请求、响应和身份验证详细信息,直到 HTTP 任务按预期运行。

在 Step Functions 控制台中测试 HTTP 任务状态
  1. 打开 Step Functions 控制台

  2. 选择创建状态机开始创建状态机,或选择包含 HTTP 任务的现有状态机。

    如果您要在现有状态机中测试任务,请参阅步骤 4。

  3. 在 Workflow Studio 的设计模式中,直观地配置 HTTP 任务。或者选择代码模式,从本地开发环境中复制粘贴状态机定义。

  4. 在设计模式下,从 Workflow Studio 的 Inspector 面板中选择测试状态

  5. 测试状态对话框中,执行以下操作:

    1. 对于执行角色,选择一个执行角色来测试状态。如果您没有权限足够的角色来配置 HTTP 任务,请参阅在 Workflow Studio 中测试 HTTP 任务的角色,创建一个角色。

    2. (可选)针对测试提供所选状态需要的任何 JSON 输入。

    3. 对于检查级别,保留默认选择信息。此级别会显示 API 调用的状态和状态输出。这对于快速检查 API 响应很有用。

    4. 选择开始测试

    5. 如果测试成功,则状态输出会显示在测试状态对话框的右侧。如果测试失败,系统会显示错误。

      在对话框的状态详细信息选项卡中,您可以看到状态定义和指向 EventBridge 连接的链接。

    6. 检查级别更改为跟踪。此级别会显示原始的 HTTP 请求和响应,对于验证标头、查询参数和其他特定于 API 的详细信息非常有用。

    7. 选中显示密钥复选框。结合跟踪检查级别,此设置可让您查看 EventBridge 连接插入的敏感数据,例如 API 密钥。您用于访问控制台的 IAM 用户身份必须具有执行 states:RevealSecrets 操作的权限。如果没有此权限,则在您开始测试时 Step Functions 会抛出访问遭拒错误。有关设置 states:RevealSecrets 权限的 IAM 策略示例,请参阅IAM使用 TestState API 的权限

      下图显示了成功的 HTTP 任务测试。此状态的检查级别设置为跟踪。下图中的 HTTP 请求和响应选项卡显示了第三方 API 调用的结果。

      
                                在跟踪级别,所选状态的测试成功的输出。
    8. 选择开始测试

    9. 如果测试成功,您可以在 HTTP 请求和响应选项卡下看到 HTTP 详细信息。

不支持的 HTTP 任务响应

如果返回的响应满足以下任意条件,则 HTTP 任务失败并显示 States.Runtime 错误:

  • 响应包含 application/octet-streamimage/*video/*audio/* Content-Type 标头。

  • 响应无法读取为有效字符串。例如,二进制数据或图像数据。