如何在 REST API 中映射 API Gateway 整合的回應狀態碼?

上次更新日期:2022 年 9 月 30 日

為什麼 AWS Lambda 會在 REST API 中傳回 200 正常狀態碼回應?

如何在 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 回應碼。若您需要建立自訂回應碼,請使用非 Proxy 整合和映射範本。

使用自訂碼設定回應方法

請依照下列步驟設定方法,使用 API Gateway 的自訂回應程式碼來進行回應:

1.    在 API Gateway 主控台中,建立公有 REST API

2.    建立資源和資源方法。

3.    設定包含您希望 API Gateway 傳回之狀態碼的方法回應。

4.    設定 Lambda 整合回應

  • 針對 Lambda 錯誤規則運算式,請為 Lambda 函數傳回的錯誤訊息提供規則運算式模式。
    注意:您還可以找到 HTTP 回應的 HTTP 錯誤規則運算式
  • 針對方法回應狀態,請提供 API Gateway 必須傳回的狀態碼。
  • 選擇 Content Handling (內容處理) 的選項,以設定在將回應傳送至用戶端之前處理回應內文的方式。
  • 確認預設模式的狀態碼設定為 200。

5.    完成設定整合回應之後,請儲存、測試及部署變更。

將狀態碼映射至靜態值

若要讓 API Gateway 擷取從後端傳回的一組狀態碼,請將狀態碼映射至靜態值:

1.    前往具有您要變更之狀態碼的資源。

2.    將方法回應設定為傳回 400 作為 API Gateway 回應碼。

3.    返回資源組態並設定整合回應。

4.    HTTP 狀態規則運算式中的值會擷取後端傳回的狀態。然後,狀態會映射至步驟 2 中定義的回應碼。

HTTP 狀態規則運算式具有預設值 "-" 並映射至 200 作為方法響應狀態,則會擷取所有狀態碼並透過後端映射傳回 200。您可以將 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。