为什么 AWS Lambda 在 REST API 中返回 200 OK 状态代码响应?
如何在 Amazon API Gateway 中映射 REST API 返回的状态代码?
-或者-
如何在 REST API 中映射状态代码?
解决方法
如果您想要覆盖后端响应状态代码,请使用 API Gateway 映射模板或正则表达式来映射状态代码。您可以在与 REST API 的代理和非代理集成中执行此操作。
代理和非代理集成用于在 REST API 中映射响应状态代码。当有代理响应时,API Gateway 会收到后端发送的状态代码。在 Lambda 代理集成中,API Gateway 要求后端 Lambda 函数以 JSON 格式返回以下输出:
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
"body": “…”65411
}
在与 Lambda 函数的代理集成中,状态代码从后端 Lambda 函数直接传递到 API Gateway。在非代理集成中,不能直接从 Lambda 函数传递状态代码。
当 API Gateway 成功调用 Lambda 函数时,默认响应状态代码为 200。当 Lambda 遇到错误时,也会返回状态代码。您可以自定义 API Gateway 响应代码。如果需要创建自定义响应代码,请使用非代理集成和映射模板。
使用自定义代码配置响应方法
按照以下步骤配置通过 API Gateway 中的自定义响应代码来进行响应的方法:
1. 在 API Gateway 控制台中,创建一个公共 REST API。
2. 创建资源并为该资源创建方法。
3. 设置包含您希望 API Gateway 返回的状态代码的方法响应。
4. 配置 Lambda 集成响应。
- 对于 Lambda Error Regex(Lambda 错误正则表达式),请为 Lambda 函数返回的错误消息提供正则表达式模式。
注意:您还可以找到 HTTP 响应的 HTTP 错误正则表达式。
- 对于方法响应状态,请提供 API Gateway 必须返回的状态代码。
- 为 Content Handling(内容处理)选择一个选项,以设置在将响应发送到客户端之前如何处理响应正文。
- 确保将状态代码的默认模式设置为 200。
5. 配置完集成响应后,保存、测试和部署您的更改。
将状态代码映射到静态值
要让 API Gateway 捕获从后端返回的一组状态状态,请将状态代码映射到静态值:
1. 转到具有要更改的状态代码的资源。
2. 将方法响应设置为返回 400 作为 API Gateway 响应代码。
3. 返回资源配置并设置集成响应。
4. HTTP status regex(HTTP 状态正则表达式)中的值将捕获后端返回的状态。然后将状态映射到步骤 2 中定义的响应代码。
当 HTTP status regex(HTTP 状态正则表达式)的默认值为“-”并映射到 200 作为方法响应状态时,所有状态代码都会被捕获并由后端映射返回到 200。您可以将 HTTP status regex(HTTP 状态正则表达式)值更改为 2\d{2},以捕获所有 2xx 响应并将它们映射到 200。
5. 选择 Add integration response(添加集成响应)以捕获其他状态代码。
对于 4xx,在 HTTP status regex(HTTP 状态正则表达式)中,添加 4\d{2}。对于 Method response status(方法响应状态),请选择 400。这是在步骤 2 中定义的。
6. 部署您的 API。当 API 返回任何 2xx 状态代码时,它们将映射到 200 状态代码。如果您的 API 返回任何 4xx 状态代码,则它们将映射到 400 状态代码。
正则表达式可以通过多种方式进行格式化。例如:
- .*([01][0-9][0-9]|2[0-4][0-9]|25[0-5]).* 匹配100-199、200-249 或 250-255 之间的状态代码。
- .*5\d\d.* 匹配状态代码,例如 5xx。
以下示例代码用于测试 Lambda 函数:
def lambda_handler(event, context):
if "error" not in event or event['error'] == "":
return("Pass")
elif event['error'] == 'sample 400':
raise Exception({"errorMessage": "Error: Raising 400 from within the Lambda function","errorType": "Exception"})
elif event['error'] == 'sample 500':
raise Exception({"errorMessage": "Error: Raising 500 from within the Lambda function","errorType": "Exception"})
else:
return("Error Value in the json request should either be 400 or 500 to demonstrate")
在该示例中,代码检查从 API Gateway 发送的错误值是 400 还是 500 错误。当错误为 400 或 500 时,Lambda 代码会引发异常并显示一条错误消息。当 API Gateway 收到响应时,服务会检查该错误消息是否与集成响应中配置的任何模式相匹配。如果 Lambda 正则表达式模式匹配,则 API Gateway 会相应地做出响应。
7. 成功配置后,可以使用 API Gateway 控制台测试状态代码。
使用映射模板映射状态代码
前面的示例使用正则表达式,它也可以使用映射模板。以下示例将覆盖来自后端的 200 状态代码以应用 400 状态代码:
1. 使用以下示例代码创建 Lambda 函数:
----------------------
def lambda_handler(event, context):
# TODO implement print(event)
return { 'statusCode': 200, 'body': "customerror" }
-----------------------
2. 使用前面的 Lambda 函数为后端创建具有 Lambda 非代理集成的 API。
3. 按照使用 API Gateway 控制台覆盖 API 的响应状态代码教程中所述的步骤 6-10 执行操作。
在此示例中,使用以下映射模板:
----------------------
#set($inputRoot = $input.path('$'))
$input.json("$")
#if($inputRoot.toString().contains("customerror"))
#set($context.responseOverride.status = 400)
#end
----------------------
4. 保存、测试和部署 API。
相关信息
使用模型和映射模板
转换 API 请求和响应
Amazon API Gateway 开发人员指南