

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 了解 Lambda 函數調用方法
<a name="lambda-invocation"></a>

部署 Lambda 函數之後，可以透過多種方式調用它：
+ [Lambda 主控台](testing-functions.md)：使用 Lambda 主控台快速建立測試事件以調用函數。
+ SDK [AWS](https://aws.amazon.com/developer/tools/) – 使用 AWS SDK 以程式設計方式叫用您的 函數。
+ [調用](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html) API：使用 Lambda 調用 API 以直接調用您的 函數。
+ [AWS Command Line Interface (AWS CLI)](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/invoke.html) – 使用 `aws lambda invoke` AWS CLI 命令直接從命令列叫用函數。
+ [函數 URL HTTP(S) 端點](urls-configuration.md)：使用函數 URL 建立專用 HTTP(S) 端點，可用來調用函數。

所有這些方法都是調用函數的*直接*方式。在 Lambda 中，常見的使用案例是根據應用程式中其他位置發生的事件調用函數。有些服務可以調用 Lambda 函數來處理每個新事件。這稱為[觸發條件](lambda-services.md)。對於串流和佇列型服務，Lambda 會調用函數來處理批次記錄。這稱為[事件來源映射](invocation-eventsourcemapping.md)。

當您調用函式時，您可以選擇以同步或非同步方式進行調用。使用[同步調用](invocation-sync.md)，您會等待函式處理事件並傳回回應。使用[非同步](invocation-async.md)調用，Lambda 會將事件排入佇列以進行處理，並立即傳回回應。[調用 API 中的 `InvocationType` 請求參數](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html#API_Invoke_RequestParameters)決定 Lambda 如何調用函數。值 `RequestResponse` 表示同步調用，值 `Event` 表示非同步調用。

若要透過 IPv6 調用您的函數，請使用 Lambda 的公有[雙堆疊端點](https://docs.aws.amazon.com/general/latest/gr/rande.html#dual-stack-endpoints)。雙堆疊端點可同時支援 IPv4 和 IPv6。Lambda 雙堆疊端點使用下列語法：

```
protocol://lambda.us-east-1.api.aws
```

也可以使用 [Lambda 函數 URL](urls-configuration.md) 透過 IPv6 來調用函數。函數 URL 端點的格式如下：

```
https://url-id.lambda-url.us-east-1.on.aws
```

如果函數調用導致錯誤，則對於同步調用，請檢視回應中的錯誤訊息，並手動重試調用。對於非同步調用，Lambda 會自動處理重試，並可將調用記錄傳送至[目的地](invocation-async-retain-records.md#invocation-async-destinations)。

# 同步調用 Lambda 函數
<a name="invocation-sync"></a>

當您以同步方式調用函數時，Lambda 會執行函數並等候回應。當函數執行完成時，Lambda 會從函數的程式碼傳回回應，其中包含調用的函數版本等額外資料。若要透過 AWS CLI 以同步方式調用函式，請使用 `invoke` 命令。

```
aws lambda invoke --function-name my-function \
    --cli-binary-format raw-in-base64-out \
    --payload '{ "key": "value" }' response.json
```

如果您使用 AWS CLI 第 2 版，則需要 **cli-binary-format** 選項。若要讓此成為預設的設定，請執行 `aws configure set cli-binary-format raw-in-base64-out`。若要取得更多資訊，請參閱*《AWS Command Line Interface 使用者指南第 2 版》*中 [AWS CLI 支援的全域命令列選項](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)。

您應該會看到下列輸出：

```
{
    "ExecutedVersion": "$LATEST",
    "StatusCode": 200
}
```

下圖顯示以同步方式調用 Lambda 函數的用戶端。Lambda 會將事件直接傳送到函數，並將函數的回應傳送回調用者。

![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/invocation-sync.png)


`payload` 是包含 JSON 格式事件的字串。AWS CLI 從該函數寫入回覆的檔案名稱是 `response.json`。如果函數傳回物件或錯誤，則回應內文是 JSON 格式的物件或錯誤。如果函數結束時沒有錯誤，則回應內文為 `null`。

**注意**  
在傳送回應之前，Lambda 不會等待外部擴充功能完成。外部延伸項目會在執行環境中做為獨立的處理序執行，並在函數調用完成之後繼續執行。如需更多詳細資訊，請參閱 [使用 Lambda 擴充功能來增強 Lambda 函數](lambda-extensions.md)。

命令的輸出會顯示於終端機，包括來自 Lambda 的回應中標頭中的資訊。這包括處理事件的版本 (當您使用[別名](configuration-aliases.md)時很實用)，以及 Lambda 傳回的狀態碼。如果 Lambda 能夠執行函數，則狀態碼為 200，即使函數傳回了錯誤。

**注意**  
對於逾時很久的函式，您的用戶端可能在等待回應的同時，在同步調用期間中斷連線。設定您的 HTTP 用戶端、SDK、防火牆、Proxy 或作業系統，以透過逾時或持續作用設定允許長時間連線。

如果 Lambda 無法執行函數，錯誤則會顯示在輸出中。

```
aws lambda invoke --function-name my-function \
    --cli-binary-format raw-in-base64-out \
    --payload value response.json
```

您應該會看到下列輸出：

```
An error occurred (InvalidRequestContentException) when calling the Invoke operation: Could not parse request body into json: Unrecognized token 'value': was expecting ('true', 'false' or 'null')
 at [Source: (byte[])"value"; line: 1, column: 11]
```

AWS CLI 是開放原始碼工具，可讓您在命令列 shell 中使用命令來與 AWS 服務互動。若要完成本節中的步驟，您必須擁有 [AWS CLI 版本 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

您可以透過 [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)，使用 `--log-type` 命令選項來擷取要調用的日誌。其回應將包含 `LogResult` 欄位，內含該次調用的 base64 編碼日誌 (最大達 4 KB)。

**Example 擷取日誌 ID**  
下列範例顯示如何從名稱為 `my-function` 的函數的 `LogResult` 欄位來擷取*日誌 ID*。  

```
aws lambda invoke --function-name my-function out --log-type Tail
```
您應該會看到下列輸出：  

```
{
    "StatusCode": 200,
    "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...",
    "ExecutedVersion": "$LATEST"
}
```

**Example 解碼日誌**  
在相同的命令提示中，使用 `base64` 公用程式來解碼日誌。下列範例顯示如何擷取 `my-function` 的 base64 編碼日誌。  

```
aws lambda invoke --function-name my-function out --log-type Tail \
--query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode
```
如果您使用 AWS CLI 第 2 版，則需要 **cli-binary-format** 選項。若要讓此成為預設的設定，請執行 `aws configure set cli-binary-format raw-in-base64-out`。若要取得更多資訊，請參閱*《AWS Command Line Interface 使用者指南第 2 版》*中 [AWS CLI 支援的全域命令列選項](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)。  
您應該會看到下列輸出：  

```
START RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Version: $LATEST
"AWS_SESSION_TOKEN": "AgoJb3JpZ2luX2VjELj...", "_X_AMZN_TRACE_ID": "Root=1-5d02e5ca-f5792818b6fe8368e5b51d50;Parent=191db58857df8395;Sampled=0"",ask/lib:/opt/lib",
END RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8
REPORT RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8  Duration: 79.67 ms      Billed Duration: 80 ms         Memory Size: 128 MB     Max Memory Used: 73 MB
```
該 `base64` 公用程式可在 Linux、macOS 和 [Ubuntu on Windows](https://docs.microsoft.com/en-us/windows/wsl/install-win10) 上使用。macOS 使用者可能需要使用 `base64 -D`。

如需有關 `Invoke` API 的詳細資訊 (包括參數、標頭和錯誤的完整清單)，請參閱[調用](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)。

當您直接調用函式時，您可以檢查回應中是否有錯誤並重試。AWS CLI 和 AWS SDK 也會在用戶端逾時、調節和服務錯誤時自動重試。如需更多詳細資訊，請參閱 [了解 Lambda 中的重試行為](invocation-retries.md)。

# 非同步調用 Lambda 函數
<a name="invocation-async"></a>

數個 AWS 服務 (例如 Amazon Simple Storage Service (Amazon S3) 和 Amazon Simple Notiﬁcation Service (Amazon SNS)) 會以非同步方式調用函數以處理事件。您也可以使用 AWS Command Line Interface (AWS CLI) 或其中一個 AWS SDK 以非同步方式調用 Lambda 函數。當您以非同步方式呼叫函數時，您不需要等待來自函數程式碼的回應。您可以將事件傳遞給 Lambda，而 Lambda 會處理其餘的工作。您可以設定 Lambda 處理錯誤的方式，且可將調用記錄傳送至 Amazon Simple Queue Service (Amazon SQS) 或 Amazon EventBridge (EventBridge) 這類下游資源，以便將您應用程式的元件鏈結在一起。

下圖顯示以非同步方式來調用 Lambda 函數的用戶端。Lambda 會先將事件排入佇列，再將事件傳送到函數。

![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/features-async.png)


針對非同步調用，Lambda 會將事件置放在佇列中，並傳回成功回應，其中不包含其他資訊。單獨的程序會從佇列讀取事件，並將事件傳送到您的函數。

 若要使用 AWS Command Line Interface (AWS CLI) 或其中一個 AWS SDK 以非同步方式調用 Lambda 函數，須將 [InvocationType](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html#lambda-Invoke-request-InvocationType) 參數設定為 `Event`。以下是使用 AWS CLI 命令調用函數的範例。

```
aws lambda invoke \
  --function-name my-function  \
  --invocation-type Event \
  --cli-binary-format raw-in-base64-out \
  --payload '{ "key": "value" }' response.json
```

您應該會看到下列輸出：

```
{
    "StatusCode": 202
}
```

如果您使用 AWS CLI 第 2 版，則需要 **cli-binary-format** 選項。若要讓此成為預設的設定，請執行 `aws configure set cli-binary-format raw-in-base64-out`。若要取得更多資訊，請參閱*《AWS Command Line Interface 使用者指南第 2 版》*中 [AWS CLI 支援的全域命令列選項](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)。

輸出檔 (`response.json`) 不包含任何資訊，但仍會在您執行此命令時建立。如果 Lambda 無法將事件新增到佇列，錯誤訊息就會顯示在命令輸出中。

# Lambda 如何處理非同步調用的錯誤和重試
<a name="invocation-async-error-handling"></a>

Lambda 會管理函數的非同步事件佇列，並在發生錯誤時嘗試重試。依預設，如果函數傳回錯誤，則 Lambda 會嘗試多執行函數兩次，且兩次嘗試之間等候一分鐘，而第二次和第三次嘗試之間等候兩分鐘。函式錯誤包含函式程式碼所傳回的錯誤，以及函式執行時間所傳回的錯誤，例如逾時。

如果函式沒有足夠的並行可用來處理所有事件，則額外請求會遭到調節。依預設，對於調節錯誤 (429) 和系統錯誤 (500 序列)，Lambda 會將事件傳回到佇列，並嘗試再次執行函數長達 6 小時。重試間隔從第一次嘗試後的 1 秒呈指數增加到最多 5 分鐘。如果佇列包含許多項目，Lambda 會增加重試間隔，並降低從佇列讀取事件的速率。

即使您的函數並未傳回錯誤，它也可以從 Lambda 收到相同的事件很多次，因為佇列本身最終一致。如果函式來不及處理傳入事件，也可以從佇列中刪除事件，而不需傳送到函式。確保您的函式程式碼可從容地處理重複的事件，而且您有足夠的並行可用來處理所有調用。

當佇列很長時，新的事件可能會在 Lambda 有機會將其傳送到函數前就已過期。當事件過期時或所有處理嘗試皆失敗時，Lambda 便會捨棄該事件。您可以[設定函數的錯誤處理](invocation-async-configuring.md)，以減少 Lambda 執行的重試次數，或更快地捨棄未處理的事件。若要擷取已捨棄的事件，請為函式[設定無效字母佇列](invocation-async-retain-records.md#invocation-dlq)。若要擷取調用失敗的記錄 (例如逾時或執行時期錯誤)，請[建立失敗時目的地](invocation-async-retain-records.md#invocation-async-destinations)。

# 設定 Lambda 非同步調用的錯誤處理
<a name="invocation-async-configuring"></a>

使用以下設定，設定 Lambda 在非同步調用函數時如何處理錯誤和重試：
+ [MaximumEventAgeInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_PutFunctionEventInvokeConfig.html#lambda-PutFunctionEventInvokeConfig-request-MaximumEventAgeInSeconds)：Lambda 在捨棄事件之前，將事件保留在非同步事件佇列中的時間上限，以秒為單位。
+ [MaximumRetryAttempts](https://docs.aws.amazon.com/lambda/latest/api/API_PutFunctionEventInvokeConfig.html#lambda-PutFunctionEventInvokeConfig-request-MaximumRetryAttempts)：當函數傳回錯誤時，Lambda 重試的次數上限。

使用 Lambda 主控台或 AWS CLI 設定函數、版本或別名的錯誤處理設定。

------
#### [ Console ]

**設定錯誤處理**

1. 開啟 Lambda 主控台中的 [函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇一個函數。

1. 選擇**組態**，然後選擇**非同步調用**。

1. 在 **非同步調用** 下方，選擇 **編輯**。

1. 進行下列設定。
   + **Maximum age of event** (事件存留期上限) - Lambda 在非同步事件佇列中保留事件的時間上限，最多 6 小時。
   + **Retry attempts** (重試嘗試) - 當函數傳回錯誤時，Lambda 重試的次數上限 (介於 0 到 2)。

1. 選擇**儲存**。

------
#### [ AWS CLI ]

若要使用 AWS CLI 設定非同步調用，請使用 [put-function-event-invoke-config](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/put-function-event-invoke-config.html) 命令。下列範例會設定事件存留期為 1 小時且不重試的函數。

```
aws lambda put-function-event-invoke-config \ 
  --function-name error \
  --maximum-event-age-in-seconds 3600 \
  --maximum-retry-attempts 0
```

此 `put-function-event-invoke-config` 命令會覆寫任何在函數、版本或別名上的現有組態。若要設定某個選項而不重設其他選項，請使用 [update-function-event-invoke-config](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-event-invoke-config.html)。下列範例會將 Lambda 設定為在無法處理事件時，將記錄傳送至名為 `destination` 的標準 SQS 佇列。

```
aws lambda update-function-event-invoke-config \
  --function-name my-function \
  --destination-config '{"OnFailure":{"Destination": "arn:aws:sqs:us-east-1:123456789012:destination"}}'
```

------

您應該會看到下列輸出：

```
{
    "LastModified": 1573686021.479,
    "FunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function:$LATEST",
    "MaximumRetryAttempts": 0,
    "MaximumEventAgeInSeconds": 3600,
    "DestinationConfig": {
        "OnSuccess": {},
        "OnFailure": {}
    }
}
```

當調用事件超過最大存留期，或所有重試嘗試都失敗時，Lambda 會將其捨棄。若要保留已捨棄事件的副本，請設定失敗事件的[目的地](invocation-async-retain-records.md#invocation-async-destinations)。

# 擷取 Lambda 非同步調用的記錄
<a name="invocation-async-retain-records"></a>

Lambda 可以將非同步調用的記錄傳送到下列其中一項 AWS 服務。
+ **Amazon SQS**：標準 SQS 佇列
+ **Amazon SNS**：標準 SNS 主題
+ **Amazon S3**：Amazon S3 儲存貯體 (僅限失敗時)
+ **AWS Lambda**：Lambda 函數
+ **Amazon EventBridge**：EventBridge 事件匯流排

呼叫記錄包含請求和回應 (JSON 格式) 的詳細資訊。您可以為成功處理的事件及所有處理嘗試皆失敗的事件設定個別目標。或者，您可以將標準 Amazon SQS 佇列或標準 Amazon SNS 主題設為捨棄事件的無效字母佇列。針對無效字母佇列，Lambda 只會傳送事件的內容，而不包含回應的詳細資訊。

如果 Lambda 無法將記錄傳送到您設定的目的地，便會將 `DestinationDeliveryFailures` 指標傳送至 Amazon CloudWatch。如果您的組態中包含不受支援的目的地類型 (例如 Amazon SQS FIFO 佇列或 Amazon SNS FIFO 主題)，就可能發生這種情形。傳遞錯誤也可能因許可錯誤和大小限制而發生。如需 Lambda 調用指標的詳細資訊，請參閱：[呼叫指標](monitoring-metrics-types.md#invocation-metrics)

**注意**  
為了防止函數觸發，您可以將函數的預留並行設為零。當您將非同步調用函數的預留並行設定為零時，Lambda 會開始將新事件傳送至設定的[無效字母佇列](#invocation-dlq)或失敗時的[事件目的地](#invocation-async-destinations)，不會進行任何重試。若要處理在預留並行設定為零時傳送的事件，您必須使用來自無效字母佇列或失敗時的事件目的地之事件。

## 新增目的地
<a name="invocation-async-destinations"></a>

若要保留非同步調用的記錄，請將目的地新增至您的函數。您可以選擇將成功或失敗的調用傳送至目的地。每個函數都可以有多個目的地，因此您可以為成功和失敗的事件配置單獨的目的地。傳送至目的地的每筆記錄都是包含調用之詳細資訊的 JSON 文件。與錯誤處理設定相似，您可以設定函數、函數版本或是別名的目標。

**提示**  
您也可以保留下列事件來源映射類型的呼叫失敗記錄：[Amazon Kinesis](kinesis-on-failure-destination.md#kinesis-on-failure-destination-console)、[Amazon DynamoDB](services-dynamodb-errors.md) 和 [Apache Kafka (Amazon MSK 和自我管理 Apache Kafka)](kafka-on-failure.md#kafka-onfailure-destination)。<a name="destinations-permissions"></a>

以下資料表列出針對非同步調用記錄支援的目的地。若要讓 Lambda 成功將記錄傳送至您選擇的目的地，請確定函數的[執行角色](lambda-intro-execution-role.md)也包含相關許可。此資料表也說明每個目的地類型如何接收 JSON 調用記錄。


| 目的地類型 | 所需的許可 | 目的地特定 JSON 格式 | 
| --- | --- | --- | 
|  Amazon SQS 佇列  |  [sqs:SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)  |  Lambda 會將調用記錄做為 `Message` 傳遞至目的地。  | 
|  Amazon SNS 主題  |  [sns:Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html)  |  Lambda 會將調用記錄做為 `Message` 傳遞至目的地。  | 
|  Amazon S3 儲存貯體 (僅限失敗時)  |  [s3:PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) [s3:ListBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/invocation-async-retain-records.html)  | 
|  Lambda 函式  |  [lambda:InvokeFunction](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)  |  Lambda 傳遞調用記錄會以承載形式傳遞給函數。  | 
|  EventBridge  |  [events:PutEvents](https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutEvents.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/invocation-async-retain-records.html)  | 

**注意**  
對於 Amazon S3 目的地，如果您已使用 KMS 金鑰在相應儲存貯體上啟用加密，則函數也需要 [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) 許可。

**重要**  
若以 Amazon SNS 為目的地，注意 Amazon SNS 的訊息大小上限為 256 KB。若非同步調用承載接近 1 MB，則調用記錄 (包含原始承載與額外中繼資料) 可能會超過 Amazon SNS 的上限，導致傳送失敗。建議將 Amazon SQS 或 Amazon S3 用作較大承載的目的地。

以下步驟說明如何使用 Lambda 主控台和 AWS CLI為函式設定目的地。

------
#### [ Console ]

1. 開啟 Lambda 主控台中的 [函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇一個函數。

1. 在**函數概觀下**，選擇**新增目的地**。

1. 針對**來源**，選擇**非同步調用**。

1. 如為**條件**，請從下列選項中選擇：
   + **On failure** (失敗時) - 當事件的所有處理嘗試都失敗，或超過存留期上限時，傳送記錄。
   + **成功時** - 當函數成功處理非同步調用時傳送記錄。

1. 對於**目的地類型**，請選擇接收調用記錄的資源類型。

1. 對於**目的地**，請選擇一個資源。

1. 選擇**儲存**。

------
#### [ AWS CLI ]

若要使用 設定目的地 AWS CLI，請執行 [update-function-event-invoke-config](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-event-invoke-config.html) 命令。下列範例會將 Lambda 設定為在無法處理事件時，將記錄傳送至名為 `destination` 的標準 SQS 佇列。

```
aws lambda update-function-event-invoke-config \
  --function-name my-function \
  --destination-config '{"OnFailure":{"Destination": "arn:aws:sqs:us-east-1:123456789012:destination"}}'
```

------

### Amazon S3 目的地的安全最佳實務
<a name="s3-destination-security"></a>

刪除已設定為目的地的 S3 儲存貯體而不從函數的組態中移除目的地，可能會產生安全風險。如果其他使用者知道目的地儲存貯體的名稱，他們可以在其 AWS 帳戶中重新建立儲存貯體。失敗調用的記錄會被傳送到其儲存貯體，可能公開來自您函數的資料。

**警告**  
為了確保無法將函數的調用記錄傳送到另一個 中的 S3 儲存貯體 AWS 帳戶，請將條件新增至函數的執行角色，以限制您帳戶中儲存貯體的`s3:PutObject`許可。

下列範例顯示的 IAM 政策，將函數的 `s3:PutObject` 許可限制為帳戶中的儲存貯體。此政策也為 Lambda 提供了使用 S3 儲存貯體做為目的地所需的 `s3:ListBucket` 許可。

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "S3BucketResourceAccountWrite",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::*/*",
                "arn:aws:s3:::*"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:ResourceAccount": "111122223333"
                }
            }
        }
    ]
}
```

若要使用 AWS 管理主控台 或 將許可政策新增至函數的執行角色 AWS CLI，請參閱下列程序中的指示：

------
#### [ Console ]

**若要將許可政策新增至函數的執行角色 (主控台)**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選取您要修改其執行角色的 Lambda 函數。

1. 在**組態**索引標籤中，選擇**許可**。

1. 在**執行角色**索引標籤中，選取函數的**角色名稱**，以開啟角色的 IAM 主控台頁面。

1. 透過下列步驟將許可政策新增至角色：

   1. 在**許可政策**窗格中，選擇**新增許可** ，然後選取**建立內嵌政策**。

   1. 在**政策編輯器**中，選取 **JSON**。

   1. 將您要新增的政策貼入編輯器 (取代現有的 JSON)，然後選擇**下一步**。

   1. 在**政策詳細資訊**下，輸入**政策名稱**。

   1. 選擇**建立政策**。

------
#### [ AWS CLI ]

**若要將許可政策新增至函數的執行角色 (CLI)**

1. 建立具有所需許可的 JSON 政策文件，並將其儲存在本機目錄中。

1. 使用 IAM `put-role-policy` CLI 命令，將許可新增至函數的執行角色。從您儲存 JSON 政策文件的目錄執行下列命令，並將角色名稱、政策名稱和政策文件取代為您自己的值。

   ```
   aws iam put-role-policy \
   --role-name my_lambda_role \
   --policy-name LambdaS3DestinationPolicy \
   --policy-document file://my_policy.json
   ```

------

### 調用記錄範例
<a name="destination-example-record"></a>

當調用與條件相符時，Lambda 會將包含調用之詳細資訊的 [JSON 文件](#destinations-permissions)傳送到目的地。下列範例顯示因函式錯誤而導致處理失敗三次事件的呼叫記錄。

**Example**  

```
{
    "version": "1.0",
    "timestamp": "2019-11-14T18:16:05.568Z",
    "requestContext": {
        "requestId": "e4b46cbf-b738-xmpl-8880-a18cdf61200e",
        "functionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function:$LATEST",
        "condition": "RetriesExhausted",
        "approximateInvokeCount": 3
    },
    "requestPayload": {
        "ORDER_IDS": [
            "9e07af03-ce31-4ff3-xmpl-36dce652cb4f",
            "637de236-e7b2-464e-xmpl-baf57f86bb53",
            "a81ddca6-2c35-45c7-xmpl-c3a03a31ed15"
        ]
    },
    "responseContext": {
        "statusCode": 200,
        "executedVersion": "$LATEST",
        "functionError": "Unhandled"
    },
    "responsePayload": {
        "errorMessage": "RequestId: e4b46cbf-b738-xmpl-8880-a18cdf61200e Process exited before completing request"
    }
}
```

呼叫記錄包含事件、回應以及記錄傳送原因的詳細資訊。

### 追蹤傳至目的地的請求
<a name="destinations-tracing"></a>

您可以使用 AWS X-Ray 查看每個請求排入佇列、由 Lambda 函數處理並傳遞至目的地服務的連接檢視。為調用函數的函數或服務啟用 X-Ray 追蹤時，Lambda 會將 X-Ray 標頭新增至請求，並將標頭傳送至目的地服務。來自上游服務的追蹤會自動連結至來自下游 Lambda 函數和目的地服務的追蹤，進而建立整個應用程式的端對端檢視。如需追蹤的詳細資訊，請參閱：[使用 視覺化 Lambda 函數叫用 AWS X-Ray](services-xray.md)。

## 新增無效字母佇列
<a name="invocation-dlq"></a>

做為[失敗目標](#invocation-async-destinations)的替代項目，您可以設定您的函數，使其具備一個無效字母佇列來儲存捨棄的事件，以供後續處理。無效字母佇列的運作方式與失敗目標相同，會在事件的所有處理嘗試失敗，或是在沒有處理的情況下過期時使用。不過，您只能在函數層級新增或移除無效字母佇列。函數版本使用與未發布版本 (\$1LATEST) 相同的無效字母佇列設定。失敗目標也支援其他目標，並會在呼叫記錄中包含函數回應的詳細資訊。

若要重新處理無效字母佇列中的事件，請將它設定為 Lambda 函數的[事件來源](invocation-eventsourcemapping.md)。或者，您可以手動擷取事件。

您可以為無效字母佇列選擇 Amazon SQS 標準佇列或 Amazon SNS 標準主題。不支援 SQS FIFO 佇列和 Amazon SNS FIFO 主題。
+ [Amazon SQS 佇列](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-create-queue.html) - 佇列會保留失敗的事件，直到其遭到擷取為止。如果您希望單一實體 (例如 Lambda 函數或 CloudWatch 警示) 處理失敗的事件，請選擇 Amazon SQS 標準佇列。如需詳細資訊，請參閱[搭配 Amazon SQS 使用 Lambda](with-sqs.md)。
+ [Amazon SNS 主題](https://docs.aws.amazon.com/sns/latest/gsg/CreateTopic.html) - 主題會將失敗的事件轉送到一個或多個目的地。如果您希望多個實體對失敗的事件採取動作，請選擇 Amazon SNS 標準主題。例如，您可以設定一個主題，以將事件傳送到電子郵件地址、Lambda 函數及/或 HTTP 端點。如需詳細資訊，請參閱[使用 Amazon SNS 通知調用 Lambda 函數](with-sns.md)。

若要將事件傳送到佇列或主題，您的函式需要額外許可。將具有[所需許可](#destinations-permissions)的政策新增到您函數的[執行角色](lambda-intro-execution-role.md)。如果目標佇列或主題使用客戶受管 AWS KMS 金鑰加密，請確定函數的執行角色和金鑰[的資源型政策](https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html)都包含相關許可。

在建立目標及更新函式的執行角色之後，將無效字母佇列新增到您的函式。您可以設定多個函式來將事件傳送到相同的目標。

------
#### [ Console ]

1. 開啟 Lambda 主控台中的 [函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇一個函數。

1. 選擇**組態**，然後選擇**非同步調用**。

1. 在**非同步調用**下方，選擇**編輯**。

1. 將**無效字母佇列服務**設定為 **Amazon SQS** 或 **Amazon SNS**。

1. 選擇目標佇列或主題。

1. 選擇**儲存**。

------
#### [ AWS CLI ]

若要使用 設定無效字母佇列 AWS CLI，請使用 [update-function-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-configuration.html) 命令。

```
aws lambda update-function-configuration \
  --function-name my-function \
  --dead-letter-config TargetArn=arn:aws:sns:us-east-1:123456789012:my-topic
```

------

Lambda 會依現狀將事件傳送到無效字母佇列，其屬性中有額外資訊。您可以使用此資訊來識別該函式所傳回的錯誤，或建立事件與日誌或 AWS X-Ray 追蹤的關聯性。

**無效字母佇列訊息屬性**
+ **RequestID** (字串) - 調用請求的 ID。請求 ID 會出現於函式日誌中。您也可以使用 X-Ray SDK 在追蹤的屬性中記錄請求 ID。然後，您可以在 X-Ray 主控台中依請求 ID 搜尋追蹤。
+ **ErrorCode** (數字) - HTTP 狀態碼。
+ **ErrorMessage** (字串) - 第 1 KB 的錯誤訊息。

如果 Lambda 無法將訊息傳送到無效字母佇列，則會刪除事件並發出 [DeadLetterErrors](monitoring-metrics-types.md) 指標。這可能由於缺乏許可，或訊息總大小超過目標佇列或主題的限制，而發生此狀況。例如，假設一則內文大小接近 1 MB 的 Amazon SNS 通知觸發了某個函式，導致函式執行出錯。在這種情況下，Amazon SNS 新增的事件資料與 Lambda 新增的屬性結合後，可能導致訊息超過無效字母佇列中允許的大小上限。

如果您使用 Amazon SQS 作為事件來源，請對 Amazon SQS 佇列本身 (而非 Lambda 函數) 設定無效字母佇列。如需詳細資訊，請參閱[搭配 Amazon SQS 使用 Lambda](with-sqs.md)。

# 叫用耐用的 Lambda 函數
<a name="durable-invocation"></a>

持久性 Lambda 函數可以使用與預設 Lambda 函數相同的方法叫用，但對於長時間執行的執行有重要的考量。本節涵蓋叫用模式、執行管理和耐久函數的最佳實務。

## 同步調用限制
<a name="synchronous-invocation-limits"></a>

耐用 Lambda 函數的同步調用限制為 15 分鐘，與預設 Lambda 函數相同。如果您的耐用函數需要執行超過 15 分鐘，則必須以非同步方式叫用它。

**何時使用同步調用：**用於在 15 分鐘內完成的耐久函數，以及當您需要立即結果時，例如快速核准工作流程或短資料處理任務。

## 長時間執行工作流程的非同步調用
<a name="asynchronous-invocation"></a>

對於執行時間可能超過 15 分鐘的耐用函數，請使用非同步調用。這可讓函數在用戶端收到立即確認時繼續執行。

------
#### [ TypeScript ]

```
import { LambdaClient, InvokeCommand } from "@aws-sdk/client-lambda";

const client = new LambdaClient({});

// Asynchronous invocation
const command = new InvokeCommand({
  FunctionName: "my-durable-function",
  InvocationType: "Event", // Asynchronous
  Payload: JSON.stringify({ orderId: "12345" })
});

await client.send(command);
```

------
#### [ Python ]

```
import boto3
import json

client = boto3.client('lambda')

# Asynchronous invocation
response = client.invoke(
    FunctionName='my-durable-function',
    InvocationType='Event',  # Asynchronous
    Payload=json.dumps({'order_id': '12345'})
)
```

------

## 執行管理 APIs
<a name="execution-management-apis"></a>

Lambda APIs 來管理和監控持久的函數執行，包括列出執行、取得執行狀態和停止執行。

------
#### [ TypeScript ]

```
// Get execution status
const statusCommand = new InvokeCommand({
  FunctionName: "my-durable-function",
  InvocationType: "RequestResponse",
  Payload: JSON.stringify({ 
    action: "getStatus", 
    executionId: "exec-123" 
  })
});

const result = await client.send(statusCommand);
```

------
#### [ Python ]

```
# Get execution status
response = client.invoke(
    FunctionName='my-durable-function',
    InvocationType='RequestResponse',
    Payload=json.dumps({
        'action': 'get_status',
        'execution_id': 'exec-123'
    })
)
```

------

# Lambda 如何處理來自串流和佇列式事件來源的記錄
<a name="invocation-eventsourcemapping"></a>

*事件來源映射*是 Lambda 資源，可從串流和佇列式服務讀取項目，並使用成批的記錄來調用函數。在事件來源映射中，名為*事件輪詢器*的資源會主動輪詢新訊息並調用函數。依預設，Lambda 會自動擴展事件輪詢器，但對於某些事件來源類型，可以使用[佈建模式](#invocation-eventsourcemapping-provisioned-mode)來控制專用於事件來源映射的事件輪詢器數量下限和上限。

下列服務使用事件來源映射調用 Lambda 函數：
+ [Amazon DocumentDB (with MongoDB compatibility) (Amazon DocumentDB)](with-documentdb.md)
+ [Amazon DynamoDB](with-ddb.md)
+ [Amazon Kinesis](with-kinesis.md)
+ [Amazon MQ](with-mq.md)
+ [Amazon Managed Streaming for Apache Kafka (Amazon MSK)](with-msk.md)
+ [自我管理的 Apache Kafka](with-kafka.md)
+ [Amazon Simple Queue Service (Amazon SQS)](with-sqs.md)

**警告**  
Lambda 事件來源映射至少會處理每個事件一次，而且可能會重複處理記錄。為避免與重複事件相關的潛在問題，強烈建議您讓函數程式碼具有等冪性。若要進一步了解，請參閱 AWS 知識中心中的[如何使 Lambda 函數成為等](https://repost.aws/knowledge-center/lambda-function-idempotent)冪。

## 事件來源映射與直接觸發條件有何不同
<a name="eventsourcemapping-trigger-difference"></a>

有些 AWS 服務 可以使用*觸發*直接叫用 Lambda 函數。這些服務會將事件推送至 Lambda，並在發生指定事件時立即調用函數。觸發條件適用於離散事件和即時處理。當您[使用 Lambda 主控台建立觸發](lambda-services.md#lambda-invocation-trigger)時，主控台會與對應的 AWS 服務互動，以在該服務上設定事件通知。觸發條件實際上由產生事件的服務 (而非 Lambda) 儲存和管理。以下是一些使用觸發條件調用 Lambda 函數的服務範例：
+ **Amazon Simple Storage Service (Amazon S3)：**在儲存貯體中建立、刪除或修改物件時調用函數。如需詳細資訊，請參閱[教學課程：使用 Amazon S3 觸發條件調用 Lambda 函數](with-s3-example.md)。
+ **Amazon Simple Notification Service (Amazon SNS)：**當有訊息發布至 SNS 主題時調用函數。如需詳細資訊，請參閱[教學課程： AWS Lambda 搭配 Amazon Simple Notification Service 使用](with-sns-example.md)。
+ **Amazon API Gateway：**在對特定端點提出 API 請求時調用函數。如需詳細資訊，請參閱[使用 Amazon API Gateway 端點調用 Lambda 函數](services-apigateway.md)。

事件來源映射是在 Lambda 服務內建立和管理的 Lambda 資源。事件來源映射旨在處理來自佇列的大量串流資料或訊息。批次處理來自串流或佇列的記錄比個別處理記錄更有效率。

## 批次處理行為
<a name="invocation-eventsourcemapping-batching"></a>

根據預設，事件來源映射會將記錄批次處理到 Lambda 傳送給函數的單個承載中。若要微調批次處理行為，可以設定一個批次間隔 ([MaximumBatchingWindowInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumBatchingWindowInSeconds)) 和批次大小 ([BatchSize](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-response-BatchSize))。批次間隔是將記錄收集到單一承載的最長時間。批次大小是單一批次中記錄的最大數目。當下列三個條件之一成立時，Lambda 會調用您的函數：
+ **批次間隔達到其最大值。**預設批次間隔行為會有所不同，這取決於特定的事件來源。
  + **對於 Kinesis、DynamoDB 和 Amazon SQS 事件來源：**預設批次間隔為 0 秒。這表示 Lambda 會在記錄可用時立即調用函數。若要設定批次處理間隔，請設定 `MaximumBatchingWindowInSeconds`。可以將此參數設定為從 0 秒到 300 秒之間的任意值，增量為 1 秒。如果設定批次處理間隔，則在上一個函數調用完成時開始下一個批次處理間隔。
  + **如果事件來源是 Amazon MSK、自主管理 Apache Kafka 、Amazon MQ 以及 Amazon DocumentDB：**預設批次處理時段為 500 毫秒。您可以將 `MaximumBatchingWindowInSeconds` 設定為從 0 秒到 300 秒之間的任意值，增量為秒。在 Kafka 事件來源映射的佈建模式下，如果設定了批次處理時段，則下一個時段會在上一個批次完成後立即開始。在 Kafka 事件來源映射的非佈建模式下，如果設定了批次處理時段，則下一個時段會在上一個函式調用完成後立即開始。若要最大限度降低在佈建模式下使用 Kafka 事件來源映射時的延遲，請將 `MaximumBatchingWindowInSeconds` 設定為 0。此設定可確保 Lambda 在完成目前的函式調用後立即開始處理下一個批次。如需有關低延遲處理的更多資訊，請參閱[低延遲 Apache Kafka](with-kafka-low-latency.md)。
  + **對於 Amazon MQ 和 Amazon DocumentDB 事件來源：**預設批次處理時段為 500 毫秒。您可以將 `MaximumBatchingWindowInSeconds` 設定為從 0 秒到 300 秒之間的任意值，增量為秒。一旦第一條記錄到達，批次間隔就會開始。
**注意**  
因為您只能以秒為增量變更 `MaximumBatchingWindowInSeconds`，所以在變更之後無法恢復到 500 毫秒的預設批次處理間隔。要恢復預設批次間隔，必須建立新的事件來源映射。
+ **已滿足批次大小。**批次大小下限為 1。預設和最大批次大小取決於事件來源。如需這些值的詳細資訊，請參閱 `CreateEventSourceMapping` API 操作的 [BatchSize](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-BatchSize) 規格。
+ **承載大小達到 [6 MB](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html)。**您無法修改此限制。

下圖說明了這三種情況。假設批次間隔從第 `t = 7` 秒開始。在第一種情況下，批次間隔在累積 5 條記錄後在第 `t = 47` 秒達到其最大值 40 秒。在第二種情況下，批次大小在批次間隔到期之前達到 10，因此批次間隔提前結束。在第三種情況下，承載大小在批次間隔到期之前達到最大值，因此批次間隔提前結束。

![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/batching-window.png)


建議使用不同的批次與記錄大小測試，讓每個事件來源的輪詢頻率調整為函數可以多快完成作業。[CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) `BatchSize` 參數會控制每次調用時可傳送至函數的記錄數目上限。更大的批次大小通常會更有效吸收更大集合的記錄的呼叫成本，增加您的傳輸量。

Lambda 在傳送下一批進行處理前不會等待任何已設定的[擴充](lambda-extensions.md)完成。換句話說，當 Lambda 處理下一批記錄時，您的擴充功能可能會繼續執行。如果您違反任何帳戶的 [並行](lambda-concurrency.md) 設定或限制，便可能會產生限流的問題。若要偵測此是否為潛在問題，請監控您的函數，並確認您看到的 [並行指標](monitoring-concurrency.md#general-concurrency-metrics) 是否高於事件來源映射的預期值。由於兩次調用之間的時間很短，Lambda 可能會短暫報告比碎片數目更高的並行用量。即使對於沒有延伸項目的 Lambda 函數也可能如此。

根據預設，如果您的函數傳回錯誤，則事件來源映射會重新處理整個批次，直到函數成功，或批次中的項目過期為止。若要確保依序處理，事件來源映射會暫停處理受影響的碎片，直到錯誤解決為止。針對串流來源 (DynamoDB 和 Kinesis)，您可以設定函數傳回錯誤時 Lambda 重試的次數上限。導致批次未抵達函數的服務錯誤或限流不會計入重試嘗試次數。您也可以設定事件來源映射，在捨棄事件批次時將調用記錄傳送至[目的地](invocation-async-retain-records.md#invocation-async-destinations)。

## 佈建模式
<a name="invocation-eventsourcemapping-provisioned-mode"></a>

Lambda 事件來源映射使用事件輪詢器來輪詢您的事件來源，以取得新訊息。根據預設，Lambda 會根據訊息磁碟區管理這些輪詢器的自動擴展。當訊息流量增加時，Lambda 會自動增加事件輪詢器的數量以處理負載，並在流量減少時減少輪詢器。

在佈建模式中，您可以透過定義專用輪詢資源的最小和最大限制來微調事件來源映射的輸送量，這些資源仍然準備好處理預期的流量模式。這些資源的自動擴展速度快 3 倍，可處理事件流量突然峰值，並提供 16 倍的容量來處理數百萬個事件。這可協助您建置具有嚴格效能要求的高度回應事件驅動型工作負載。

在 Lambda 中，事件輪詢器是一種運算單位，具有因事件來源類型而異的輸送量功能。對於 Amazon MSK 和自我管理的 Apache Kafka，每個事件輪詢器最多可以處理 5 MB/秒的輸送量或最多 5 個並行調用。例如，如果您的事件來源產生平均承載 1 MB，且函數的平均持續時間為 1 秒，則單一 Kafka 事件輪詢器可以支援 5 MB/秒輸送量和 5 個並行 Lambda 調用 （假設沒有承載轉換）。對於 Amazon SQS，每個事件輪詢器最多可以處理每秒 1 MB 的輸送量或最多 10 個並行調用。使用佈建模式會根據您的事件輪詢器用量產生額外費用。如需定價詳細資訊，請參閱 [AWS Lambda 定價](https://aws.amazon.com/lambda/pricing/)。

佈建模式適用於 Amazon MSK、自我管理 Apache Kafka 和 Amazon SQS 事件來源。雖然並行設定可讓您控制函數的擴展，但佈建的模式可讓您控制事件來源映射的輸送量。若要確保最大效能，您可能需要獨立調整這兩個設定。

佈建模式非常適合需要一致事件處理延遲的即時應用程式，例如處理市場資料饋送的金融服務公司、提供即時個人化建議的電子商務平台，以及管理即時玩家互動的遊戲公司。

每個事件輪詢器都支援不同的輸送量容量：
+ 對於 Amazon MSK 和自我管理的 Apache Kafka：高達 5 MB/秒的輸送量或高達 5 個並行調用
+ 對於 Amazon SQS：高達 1 MB/秒的輸送量或高達 10 個並行調用或每秒高達 10 個 SQS 輪詢 API 調用。

對於 Amazon SQS 事件來源映射，您可以將輪詢器數目下限設定為 2 到 200，預設值為 2，上限為 2 到 2，000，預設值為 200。Lambda 會在設定的最小值和最大值之間擴展事件輪詢器的數量，每分鐘快速增加最多 1，000 個並行，以提供事件的一致、低延遲處理。

對於 Kafka 事件來源映射，您可以將輪詢器的最小數量設定為 1 到 200，預設值為 1，最大值為 1 到 2，000，預設值為 200。Lambda 會根據主題中的事件待處理項目，在設定的最小值和最大值之間擴展事件輪詢器的數量，以提供事件的低延遲處理。

請注意，對於 Amazon SQS 事件來源，最大並行設定不能與佈建模式搭配使用。使用佈建模式時，您可以透過最大事件輪詢器設定來控制並行。

如需設定佈建模式的詳細資訊，請參閱下列章節：
+ [設定 Amazon MSK 事件來源映射的佈建模式](kafka-scaling-modes.md)
+ [為自我管理的 Apache Kafka 事件來源映射設定佈建模式](kafka-scaling-modes.md#kafka-provisioned-mode)
+ [搭配 Amazon SQS 事件來源映射使用佈建模式](with-sqs.md#sqs-provisioned-mode)

若要將佈建模式中的延遲降至最低，請將 `MaximumBatchingWindowInSeconds`設為 0。此設定可確保 Lambda 在完成目前的函式調用後立即開始處理下一個批次。如需有關低延遲處理的更多資訊，請參閱[低延遲 Apache Kafka](with-kafka-low-latency.md)。

設定佈建模式後，可以透過監控 `ProvisionedPollers` 指標來觀察工作負載的事件輪詢器使用情況。如需詳細資訊，請參閱[事件來源映射指標](monitoring-metrics-types.md#event-source-mapping-metrics)。

## 事件來源映射 API
<a name="event-source-mapping-api"></a>

若要透過 [AWS Command Line Interface (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) 或 [AWS SDK](https://aws.amazon.com/getting-started/tools-sdks/) 來管理事件來源，可以使用下列 API 操作：
+ [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html)
+ [ListEventSourceMappings](https://docs.aws.amazon.com/lambda/latest/api/API_ListEventSourceMappings.html)
+ [GetEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_GetEventSourceMapping.html)
+ [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html)
+ [DeleteEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_DeleteEventSourceMapping.html)

# 在事件來源映射上使用標籤
<a name="tags-esm"></a>

可以標記事件來源映射來組織和管理資源。標籤是與跨 AWS 服務支援的資源相關聯的自由格式索引鍵值對。如需標籤使用案例的詳細資訊，請參閱*《標記 AWS 資源和標籤編輯器指南*》中的[常見標記策略](https://docs.aws.amazon.com//tag-editor/latest/userguide/best-practices-and-strats.html#tag-strategies)。

事件來源映射與函數相關聯，而函數可以有自己的標籤。事件來源映射不會自動從函數繼承標籤。您可以使用 AWS Lambda API 來檢視和更新標籤。您也可以在 Lambda 主控台中管理特定事件來源映射時檢視和更新標籤，包括使用 Amazon SQS 佈建模式的對應。

## 使用標籤所需的許可
<a name="esm-tags-required-permissions"></a>

若要允許 AWS Identity and Access Management (IAM) 身分 (使用者、群組或角色) 讀取或設定資源上的標籤，請為其授予相應許可：
+ **lambda:ListTags**：當資源具有標籤時，將此許可授予給需要對其呼叫 `ListTags` 的任何人員。對於已標記函數，`GetFunction` 也需要此許可。
+ **lambda:TagResource**：將此許可授予給需要呼叫 `TagResource` 或在建立時執行標記的任何人員。

或者，也可以考慮授予 **lambda：UntagResource** 許可，以允許對資源進行 `UntagResource` 呼叫。

如需詳細資訊，請參閱[Lambda 適用的身分型 IAM 政策](access-control-identity-based.md)。

## 搭配使用標籤與 Lambda 主控台
<a name="tags-esm-console"></a>

您可以使用 Lambda 主控台建立具有標籤的事件來源映射、將標籤新增至現有事件來源映射，以及依標籤篩選事件來源映射，包括在 Amazon SQS 的佈建模式中設定的事件來源映射。

當使用 Lambda 主控台為支援的串流和佇列型服務新增觸發條件時，Lambda 會自動建立事件來源映射。如需這些事件來源的詳細資訊，請參閱[Lambda 如何處理來自串流和佇列式事件來源的記錄](invocation-eventsourcemapping.md)。若要在主控台中建立事件來源映射，需要滿足下列先決條件：
+ 一個函數。
+ 來自受影響服務的事件來源。

可以新增標籤，做為用於建立或更新觸發條件的相同使用者介面的一部分。

**若要在建立事件來源映射時新增標籤**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇 函數的名稱。

1. 在**函數概觀**下，選擇**新增觸發條件**。

1. 在**觸發條件組態**下面的下拉式清單中，選擇事件來源所來自的服務名稱。

1. 為事件來源提供核心組態。如需設定事件來源的詳細資訊，請查閱[使用來自其他服務的事件叫用 Lambda AWS](lambda-services.md)中相關服務的章節。

1. 在**事件來源映射組態**下，選擇**其他設定**。

1. 在**標籤**下，選擇**新增標籤**

1. 在**索引鍵**欄位中，輸入標籤索引鍵。如需有關標記限制的資訊，請參閱《* AWS *[標記資源和標籤編輯器指南》中的標記命名限制和要求](https://docs.aws.amazon.com//tag-editor/latest/userguide/best-practices-and-strats.html#id_tags_naming_best_practices)。

1. 選擇**新增**。

**若要將標籤新增至現有的事件來源映射**

1. 在 Lambda 主控台中開啟[事件來源映射](https://console.aws.amazon.com/lambda/home#/event-source-mappings)。

1. 從資源清單中，選擇與您的**函數**和**事件來源 ARN** 對應的事件來源映射的 **UUID**。

1. 從**一般組態窗格**下的索引標籤清單中，選擇**標籤**。

1. 選擇**管理標籤**。

1. 選擇 **Add new tag** (新增標籤)。

1. 在**索引鍵**欄位中，輸入標籤索引鍵。如需有關標記限制的資訊，請參閱《* AWS *[標記資源和標籤編輯器指南》中的標記命名限制和要求](https://docs.aws.amazon.com//tag-editor/latest/userguide/best-practices-and-strats.html#id_tags_naming_best_practices)。

1. 選擇**儲存**。

**若要依標籤篩選事件來源映射**

1. 在 Lambda 主控台中開啟[事件來源映射](https://console.aws.amazon.com/lambda/home#/event-source-mappings)。

1. 選取搜尋方塊。

1. 從下拉式清單中的**標籤**子標題下方，選取您的標籤索引鍵。

1. 選取**使用：「tag-name」**以查看所有標記有此索引鍵的事件來源映射，或選擇**運算子**以進一步依值篩選。

1. 選取標籤值，依標籤索引鍵和值的組合進行篩選。

搜尋方塊也支援搜尋標籤索引鍵。輸入索引鍵的名稱，以便在清單中尋找該索引鍵。

## 搭配 使用標籤 AWS CLI
<a name="tags-esm-cli"></a>

可以使用 Lambda API 在現有的 Lambda 資源 (包括事件來源映射) 上新增和移除標籤。也可以在建立事件來源映射時新增標籤，這可讓您在整個生命週期中標記資源。

### 使用 Lambda 標籤 API 來更新標籤
<a name="tags-esm-api-config"></a>

可以透過 [TagResource](https://docs.aws.amazon.com/lambda/latest/api/API_TagResource.html) 和 [UntagResource](https://docs.aws.amazon.com/lambda/latest/api/API_UntagResource.html) API 操作來新增和移除受支援 Lambda 資源的標籤。

可使用 AWS CLI來呼叫這些操作。若要將標籤新增至現有資源，請使用 `tag-resource` 命令。此範例會新增兩個標籤，一個包含索引鍵 *Department*，另一個包含索引鍵 *CostCenter*。

```
aws lambda tag-resource \
--resource arn:aws:lambda:us-east-2:123456789012:resource-type:my-resource \
--tags Department=Marketing,CostCenter=1234ABCD
```

若要移除標籤，請使用 `untag-resource` 命令。此範例會移除具有索引鍵 *Department* 的標籤。

```
aws lambda untag-resource --resource arn:aws:lambda:us-east-1:123456789012:resource-type:resource-identifier \
--tag-keys Department
```

### 在建立事件來源映射時新增標籤
<a name="tags-esm-on-create"></a>

若要建立具有標籤的新 Lambda 事件來源映射，請使用 [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) API 操作。指定 `Tags` 參數。您可以使用 `create-event-source-mapping` AWS CLI 命令和 `--tags`選項呼叫此操作。如需關於 CLI 命令的詳細資訊，請參閱《AWS CLI 命令參考》**中的 [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html)。

將 `Tags` 參數與 `CreateEventSourceMapping` 搭配使用之前，請確保您的角色除了此操作所需的一般許可外，還擁有標記資源的許可。如需有關標記許可的詳細資訊，請參閱[使用標籤所需的許可](#esm-tags-required-permissions)。

### 使用 Lambda 標籤 API 來檢視標籤
<a name="tags-esm-api-view"></a>

若要檢視套用至特定 Lambda 資源的標籤，請使用 `ListTags` API 操作。如需詳細資訊，請參閱 [ListTags](https://docs.aws.amazon.com/lambda/latest/api/API_ListTags.html)。

您可以使用 `list-tags` AWS CLI 命令呼叫此操作，方法是提供 ARN (Amazon Resource Name)。

```
aws lambda list-tags --resource arn:aws:lambda:us-east-1:123456789012:resource-type:resource-identifier
```

### 依標籤篩選資源
<a name="tags-esm-filtering"></a>

您可以使用 AWS Resource Groups Tagging API [GetResources](https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/API_GetResources.html) API 操作，依標籤篩選資源。`GetResources` 操作可接收最多 10 個篩選條件，每個篩選條件皆包含標籤索引鍵與最多 10 個標籤值。為 `GetResources` 提供一個 `ResourceType`，即可依特定資源類型進行篩選。

您可以使用 `get-resources` AWS CLI 命令呼叫此操作。如需使用 `get-resources` 的範例，請參閱《AWS CLI 命令參考》中的 [get-resources](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/resourcegroupstaggingapi/get-resources.html#examples)。**

# 控制 Lambda 將哪些事件傳送至您的函數
<a name="invocation-eventfiltering"></a>

您可以使用事件篩選來控制 Lambda 將哪些記錄從串流或佇列中傳送至函數。例如，您可以新增篩選條件，讓函數僅處理包含特定資料參數的 Amazon SQS 訊息。事件篩選僅對特定事件來源映射有效。您可以將篩選條件新增至下列事件來源映射 AWS 服務：
+ Amazon DynamoDB
+ Amazon Kinesis Data Streams
+ Amazon MQ
+ Amazon Managed Streaming for Apache Kafka (Amazon MSK)
+ 自我管理的 Apache Kafka
+ Amazon Simple Queue Service (Amazon SQS)

如需使用特定事件來源進行篩選的特定資訊，請參閱[使用具有不同 的篩選條件 AWS 服務](#filtering-by-service)。Lambda 不支援 Amazon DocumentDB 的事件篩選。

依預設，最多可以為單一事件來源映射定義五種不同的篩選條件。篩選條件透過 OR 運算邏輯關聯。如果事件來源的記錄滿足一個或多個篩選條件，則 Lambda 會在它傳送至函數的下一個事件中包含該記錄。如果全部篩選條件都不滿足，則 Lambda 會捨棄該記錄。

**注意**  
如果需要為一個事件來源定義五個以上的篩選條件，則可以為每個事件來源請求增加最多 10 個篩選條件的配額。如果您嘗試新增超過目前配額許可的篩選條件，Lambda 將在您嘗試建立事件來源時傳回錯誤。

**Topics**
+ [

## 了解事件篩選基本知識
](#filtering-basics)
+ [

## 處理不符合篩選條件標準的記錄
](#filtering-criteria-not-met)
+ [

## 篩選條件規則語法
](#filtering-syntax)
+ [

## 將篩選條件標準連接至事件來源映射 (主控台)
](#filtering-console)
+ [

## 將篩選條件標準連接至事件來源映射 (AWS CLI)
](#filtering-cli)
+ [

## 將篩選條件標準連接至事件來源映射 (AWS SAM)
](#filtering-sam)
+ [

## 篩選條件加密
](#filter-criteria-encryption)
+ [

## 使用具有不同 的篩選條件 AWS 服務
](#filtering-by-service)

## 了解事件篩選基本知識
<a name="filtering-basics"></a>

篩選條件標準 (`FilterCriteria`) 物件是由篩選條件清單 (`Filters`) 組成的結構。每個篩選條件均是定義事件篩選模式 (`Pattern`) 的結構。模式是 JSON 篩選條件規則的字串表示法。`FilterCriteria` 物件的結構如下所示。

```
{
   "Filters": [
        {
            "Pattern": "{ \"Metadata1\": [ rule1 ], \"data\": { \"Data1\": [ rule2 ] }}"
        }
    ]
}
```

補充說明，此處是篩選條件的 `Pattern` 在純文字 JSON 中擴展的值。

```
{
    "Metadata1": [ rule1 ],
    "data": {
        "Data1": [ rule2 ]
    }
}
```

篩選條件模式可以包含中繼資料屬性、資料屬性或兩者。可用的中繼資料參數和資料參數的格式會根據作為事件來源的 AWS 服務 而變化。例如，假設您的事件來源映射從 Amazon SQS 佇列中收到以下記錄：

```
{
    "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
    "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
    "body": "{\\n \"City\": \"Seattle\",\\n \"State\": \"WA\",\\n \"Temperature\": \"46\"\\n}",
    "attributes": {
        "ApproximateReceiveCount": "1",
        "SentTimestamp": "1545082649183",
        "SenderId": "AIDAIENQZJOLO23YVJ4VO",
        "ApproximateFirstReceiveTimestamp": "1545082649185"
    },
    "messageAttributes": {},
    "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
    "eventSource": "aws:sqs",
    "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue",
    "awsRegion": "us-east-2"
}
```
+ **中繼資料屬性**是包含有關建立該記錄之事件資訊的欄位。在 Amazon SQS 記錄範例中，中繼資料屬性包括 `messageID`、`eventSourceArn` 和 `awsRegion` 等欄位。
+ **資料屬性**是包含串流或佇列資料的記錄欄位。在 Amazon SQS 事件範例中，資料欄位的索引鍵為 `body`，而資料屬性為 `City`、`State` 和 `Temperature` 欄位。

不同類型的事件來源對其資料欄位使用不同的索引鍵值。若要篩選資料屬性，請務必在篩選條件模式中使用正確的索引鍵。如需資料篩選金鑰的清單，以及查看每個支援之篩選模式的範例 AWS 服務，請參閱 [使用具有不同 的篩選條件 AWS 服務](#filtering-by-service)。

事件篩選可處理多級 JSON 篩選。例如，考慮 DynamoDB 串流中的下列記錄片段：

```
"dynamodb": {
    "Keys": {
        "ID": {
            "S": "ABCD"
        }
        "Number": {
            "N": "1234"
    },
    ...
}
```

假設您只想處理排序索引鍵 `Number` 值為 4567 的記錄。在這種情況下，您的 `FilterCriteria` 物件看起來像這樣：

```
{
    "Filters": [
        {
            "Pattern": "{ \"dynamodb\": { \"Keys\": { \"Number\": { \"N\": [ "4567" ] } } } }"
        }
    ]
}
```

補充說明，此處是篩選條件的 `Pattern` 在純文字 JSON 中擴展的值。

```
{
    "dynamodb": {
        "Keys": {
            "Number": {
                "N": [ "4567" ]
                }
            }
        }
}
```

## 處理不符合篩選條件標準的記錄
<a name="filtering-criteria-not-met"></a>

Lambda 如何處理不符合篩選條件的記錄，取決於事件來源。
+ 針對 **Amazon SQS**，如果訊息不符合您的篩選條件標準，Lambda 會自動從佇列中刪除該訊息。您不需要在 Amazon SQS 中手動刪除這些訊息。
+ 針對 **Kinesis** 和 **DynamoDB**，在您的篩選條件評估一筆記錄後，串流迭代器會向前移動通過此記錄。如果記錄不滿足篩選條件標準，則無需從事件來源中手動刪除記錄。保留期之後，Kinesis 和 DynamoDB 會自動刪除這些舊記錄。如果希望更快地刪除記錄，請參閱[變更資料保留期間](https://docs.aws.amazon.com/streams/latest/dev/kinesis-extended-retention.html)。
+ 對於 **Amazon MSK**、**自我管理的 Apache Kafka** 和 **Amazon MQ** 訊息，Lambda 會捨棄不符合篩選條件中包含的所有欄位的訊息。針對 Amazon MSK 和自我管理 Apache Kafka，Lambda 會在成功調用函數之後，提交相符和不相符訊息的偏移量。若為 Amazon MQ，Lambda 會在成功調用函數後確認相符的訊息，並在篩選時確認不相符的訊息。

## 篩選條件規則語法
<a name="filtering-syntax"></a>

針對篩選條件規則，Lambda 支援 Amazon EventBridge 規則並使用與 EventBridge 相同的語法。如需詳細資訊，請參閱《Amazon EventBridge 使用者指南》**中的 [Amazon EventBridge 事件模式](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-event-patterns.html)。

以下是可用於 Lambda 事件篩選的所有比較運算子摘要。


| 比較運算子 | 範例 | Rule syntax (規則語法) | 
| --- | --- | --- | 
|  Null  |  UserID 為 Null (空值)  |  "UserID": [ null ]  | 
|  空白  |  LastName 為空白  |  "LastName": [""]  | 
|  Equals  |  名稱為「Alice」  |  "Name": [ "Alice" ]  | 
|  等於 (忽略大小寫)  |  名稱為「Alice」  |  "Name": [ \$1 "equals-ignore-case": "alice" \$1 ]  | 
|  及  |  位置為「紐約」，日期是「週一」  |  "Location": [ "New York" ], "Day": ["Monday"]  | 
|  或  |  PaymentType 為「信用卡」或「轉帳卡」  |  "PaymentType": [ "Credit", "Debit"]  | 
|  或 (多個欄位)  |  位置為「紐約」，或日期是「週一」。  |  "\$1or": [ \$1 "Location": [ "New York" ] \$1, \$1 "Day": [ "Monday" ] \$1 ]   | 
|  Not  |  天氣是「下雨」以外的任何天氣  |  "Weather": [ \$1 "anything-but": [ "Raining" ] \$1 ]  | 
|  數字 (等於)  |  價格為 100  |  "Price": [ \$1 "numeric": [ "=", 100 ] \$1 ]  | 
|  數字 (範圍)  |  價格大於 10，且小於或等於 20  |  "Price": [ \$1 "numeric": [ ">", 10, "<=", 20 ] \$1 ]  | 
|  存在  |  ProductName 已經存在  |  "ProductName": [ \$1 "exists": true \$1 ]  | 
|  不存在  |  ProductName 不存在  |  "ProductName": [ \$1 "exists": false \$1 ]  | 
|  開頭為  |  區域位於美國  |  "Region": [ \$1"prefix": "us-" \$1 ]  | 
|  Ends with  |  檔案名稱以 .png 副檔名做結尾。  |  "FileName": [ \$1 "suffix": ".png" \$1 ]   | 

**注意**  
正如 EventBridge 一般，就字串而言，Lambda 會在沒有大小寫折疊或任何其他字串標準化的情況下，使用精確字元比對。針對數字，Lambda 也會使用字串表示法。例如，300、300.0 和 3.0e2 不會被視為相等。

請注意，存在 (Exists) 運算子僅適用於事件來源 JSON 中的分葉節點。它與中繼節點不相符。例如，使用下列 JSON，篩選條件模式 `{ "person": { "address": [ { "exists": true } ] } }"` 找不到相符項目，因為 `"address"` 是中繼節點。

```
{
  "person": {
    "name": "John Doe",
    "age": 30,
    "address": {
      "street": "123 Main St",
      "city": "Anytown",
      "country": "USA"
    }
  }
}
```

## 將篩選條件標準連接至事件來源映射 (主控台)
<a name="filtering-console"></a>

依照下列步驟使用 Lambda 主控台來建立具有篩選條件標準的新事件來源映射。

**若要使用篩選條件標準 (主控台) 建立新事件來源映射**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇要建立事件來源映射的函數名稱。

1. 在**函數概觀**下，選擇**新增觸發條件**。

1. 若為 **Trigger configuration** (觸發程序組態)，選擇支援事件篩選的觸發程序類型。如需支援的服務清單，請參閱本頁開頭的清單。

1. 展開 **Additional settings** (其他設定)。

1. 在 **Filter criteria** (篩選條件標準) 下，選擇 **Add** (新增)，然後定義並輸入您的篩選條件。例如，您可以輸入下列指令。

   ```
   { "Metadata" : [ 1, 2 ] }
   ```

   這會指示 Lambda 僅處理欄位 `Metadata` 等於 1 或 2 的記錄。您可以繼續選取**新增**，新增更多篩選條件，直至達到允許的數目上限為止。

1. 完成新增篩選條件時，請選擇**儲存**。

使用主控台輸入篩選條件標準時，僅需輸入篩選模式，而不需要提供 `Pattern` 索引鍵或逸出引號。在上述指示的步驟 6 中，`{ "Metadata" : [ 1, 2 ] }` 會對應下列 `FilterCriteria`。

```
{
   "Filters": [
      {
          "Pattern": "{ \"Metadata\" : [ 1, 2 ] }"
      }
   ]
}
```

在主控台中建立事件來源映射之後，您可以在觸發程序詳細資訊中看見格式化的 `FilterCriteria`。如需有關使用主控台建立事件篩選條件的更多範例，請參閱 [使用具有不同 的篩選條件 AWS 服務](#filtering-by-service)。

## 將篩選條件標準連接至事件來源映射 (AWS CLI)
<a name="filtering-cli"></a>

假設您想要事件來源映射具有下列 `FilterCriteria`：

```
{
   "Filters": [
      {
          "Pattern": "{ \"Metadata\" : [ 1, 2 ] }"
      }
   ]
}
```

若要使用 AWS Command Line Interface (AWS CLI) 使用這些篩選條件建立新的事件來源映射，請執行下列命令。

```
aws lambda create-event-source-mapping \
    --function-name my-function \
    --event-source-arn arn:aws:sqs:us-east-2:123456789012:my-queue \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"Metadata\" : [ 1, 2 ]}"}]}'
```

此 [create-event-source-mapping](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-event-source-mapping.html) 命令會使用指定的 `FilterCriteria` 為函數 `my-function` 建立新的 Amazon SQS 事件來源映射。

若要將這些篩選條件標準新增到現有事件來源映射，請執行下列命令。

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"Metadata\" : [ 1, 2 ]}"}]}'
```

請注意，若要更新事件來源映射，您需要其 UUID。您可以從 [list-event-source-mappings](https://docs.aws.amazon.com/cli/latest/reference/lambda/list-event-source-mappings.html) 呼叫中取得 UUID。Lambda 也會在 [create-event-source-mapping](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-event-source-mapping.html) CLI 回應中傳回 UUID。

若要從事件來源移除篩選條件，可以使用空白的 `FilterCriteria` 物件執行下列 [update-event-source-mapping](https://docs.aws.amazon.com/cli/latest/reference/lambda/update-event-source-mapping.html) 命令。

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria "{}"
```

如需使用 建立事件篩選條件的更多範例 AWS CLI，請參閱 [使用具有不同 的篩選條件 AWS 服務](#filtering-by-service)。

## 將篩選條件標準連接至事件來源映射 (AWS SAM)
<a name="filtering-sam"></a>

 假設您想要在 中設定事件來源 AWS SAM ，以使用下列篩選條件：

```
{
   "Filters": [
      {
          "Pattern": "{ \"Metadata\" : [ 1, 2 ] }"
      }
   ]
}
```

 若要將這些篩選條件標準新增到事件來源映射，請將下列程式碼片段插入事件來源的 YAML 範本中。

```
FilterCriteria: 
  Filters: 
    - Pattern: '{"Metadata": [1, 2]}'
```

 如需建立和設定事件來源映射 AWS SAM 範本的詳細資訊，請參閱《 AWS SAM 開發人員指南》中的 [ EventSource](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-eventsource.html) 一節。如需使用 AWS SAM 範本建立事件篩選條件的更多範例，請參閱 [使用具有不同 的篩選條件 AWS 服務](#filtering-by-service)。

## 篩選條件加密
<a name="filter-criteria-encryption"></a>

依預設，Lambda 不會加密篩選條件物件。對於可以在篩選條件物件中包含敏感資訊的使用案例，您可以使用自己的 [KMS 金鑰](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#kms_keys)來加密它。

加密篩選條件物件後，可以使用 [GetEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_GetEventSourceMapping.html) API 呼叫檢視其純文字版本。必須具有 `kms:Decrypt` 許可，才能成功以純文字檢視篩選條件。

**注意**  
如果篩選條件物件已加密，Lambda 會在 [ListEventSourceMappings](https://docs.aws.amazon.com/lambda/latest/api/API_ListEventSourceMappings.html) 呼叫回應中修訂 `FilterCriteria` 欄位的值。反之，此欄位會顯示為 `null`。若要查看真實的 `FilterCriteria` 值，請使用 [GetEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_GetEventSourceMapping.html) API。  
若要在主控台中檢視解密的 `FilterCriteria` 值，請確定您的 IAM 角色包含 [GetEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_GetEventSourceMapping.html) 的許可。

您可以透過主控台、API/CLI 或 CloudFormation指定自己的 KMS 金鑰。

**若要使用客戶擁有的 KMS 金鑰加密篩選條件 (主控台)**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇 **Add trigger (新增觸發條件)**。如果已有觸發條件，請選擇**組態**標籤，然後選擇**觸發條件**。選取現有觸發條件，然後選擇**編輯**。

1. 選取**使用客戶管理的 KMS 金鑰加密**旁邊的核取方塊。

1. 針對**選擇客戶管理的 KMS 加密金鑰**，選取現有的已啟用金鑰或建立新的金鑰。視操作而定，您需要以下部分或全部許可：`kms:DescribeKey`、`kms:GenerateDataKey` 和 `kms:Decrypt`。使用 KMS 金鑰政策來授予這些許可。

如果您使用自己的 KMS 金鑰，必須在[金鑰政策](https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html)中允許下列 API 操作：
+ `kms:Decrypt` – 必須授予區域 Lambda 服務主體 (`lambda.AWS_region.amazonaws.com`)。這將允許 Lambda 使用此 KMS 金鑰解密資料。
  + 為了防止[跨服務混淆代理人問題](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)，金鑰政策會使用 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn) 全域條件金鑰。`aws:SourceArn` 金鑰鍵的正確值是事件來源映射資源的 ARN，因此您只有在知道其 ARN 之後，才能將此值新增至政策。在向 KMS 提出解密請求時，Lambda 也會在[加密內容](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context)中轉送 `aws:lambda:FunctionArn` 和 `aws:lambda:EventSourceArn` 金鑰及其個別值。這些值必須符合金鑰政策中指定的條件，解密請求才會成功。不需要包含 EventSourceArn for Self-managed Kafka 事件來源，因為它們沒有 EventSourceArn。
+ `kms:Decrypt` – 還必須授予想要使用金鑰在 [GetEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_GetEventSourceMapping.html) 或 [DeleteEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_DeleteEventSourceMapping.html) API 呼叫中檢視純文字篩選條件的主體。
+ `kms:DescribeKey` — 提供客戶管理之金鑰的詳細資訊，以便指定主體可以使用金鑰。
+ `kms:GenerateDataKey` – 提供許可，讓 Lambda 代表指定的主體 ([封套加密](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#enveloping)) 產生資料金鑰來加密篩選條件。

您可以使用 AWS CloudTrail 來追蹤 Lambda 代表您提出的 AWS KMS 請求。如需 CloudTrail 事件範例，請參閱 [監控 Lambda 的加密金鑰](security-encryption-at-rest.md#encryption-key-monitoring)。

我們也建議使用 [https://docs.aws.amazon.com/kms/latest/developerguide/conditions-kms.html#conditions-kms-via-service](https://docs.aws.amazon.com/kms/latest/developerguide/conditions-kms.html#conditions-kms-via-service) 條件金鑰，將 KMS 金鑰的使用限制為僅限來自 Lambda 的請求。此金鑰的值是區域 Lambda 服務主體 (`lambda.AWS_region.amazonaws.com`)。以下是授予所有相關許可的金鑰政策範例：

**Example AWS KMS 金鑰政策**    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Id": "example-key-policy-1",
    "Statement": [
        {
            "Sid": "Allow Lambda to decrypt using the key",
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.us-east-1.amazonaws.com"
            },
            "Action": [
                "kms:Decrypt"
            ],
            "Resource": "*",
            "Condition": {
                "ArnEquals" : {
                    "aws:SourceArn": [
                        "arn:aws:lambda:us-east-1:123456789012:event-source-mapping:<esm_uuid>"
                    ]
                },
                "StringEquals": {
                    "kms:EncryptionContext:aws:lambda:FunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:test-function",
                    "kms:EncryptionContext:aws:lambda:EventSourceArn": "arn:aws:sqs:us-east-1:123456789012:test-queue"
                }
            }
        },
        {
            "Sid": "Allow actions by an AWS account on the key",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Sid": "Allow use of the key to specific roles",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:role/ExampleRole"
            },
            "Action": [
                "kms:Decrypt",
                "kms:DescribeKey",
                "kms:GenerateDataKey"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals" : {
                    "kms:ViaService": "lambda.us-east-1.amazonaws.com"
                }
            }
        }
    ]
}
```

若要使用您自己的 KMS 金鑰來加密篩選條件，您也可以使用下列 [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) AWS CLI 命令。使用 `--kms-key-arn` 旗標指定 KMS 金鑰 ARN。

```
aws lambda create-event-source-mapping --function-name my-function \
    --maximum-batching-window-in-seconds 60 \
    --event-source-arn arn:aws:sqs:us-east-1:123456789012:my-queue \
    --filter-criteria "{\"filters\": [{\"pattern\": \"{\"a\": [\"1\", \"2\"]}\" }]}" \
    --kms-key-arn arn:aws:kms:us-east-1:123456789012:key/055efbb4-xmpl-4336-ba9c-538c7d31f599
```

如果已有事件來源映射，請改用 [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) AWS CLI 命令。使用 `--kms-key-arn` 旗標指定 KMS 金鑰 ARN。

```
aws lambda update-event-source-mapping --function-name my-function \
    --maximum-batching-window-in-seconds 60 \
    --event-source-arn arn:aws:sqs:us-east-1:123456789012:my-queue \
    --filter-criteria "{\"filters\": [{\"pattern\": \"{\"a\": [\"1\", \"2\"]}\" }]}" \
    --kms-key-arn arn:aws:kms:us-east-1:123456789012:key/055efbb4-xmpl-4336-ba9c-538c7d31f599
```

此操作會覆寫先前指定的 KMS 金鑰。如果您指定 `--kms-key-arn` 旗標和空引數，Lambda 會停止使用 KMS 金鑰來加密篩選條件。反之，Lambda 會預設回使用 Amazon 擁有的金鑰。

若要在 CloudFormation 範本中指定您自己的 KMS 金鑰，請使用 `AWS::Lambda::EventSourceMapping` 資源類型的 `KMSKeyArn` 屬性。例如，可以將下列程式碼片段插入事件來源的 YAML 範本。

```
MyEventSourceMapping:
  Type: AWS::Lambda::EventSourceMapping
  Properties:
    ...
    FilterCriteria:
      Filters:
        - Pattern: '{"a": [1, 2]}'
    KMSKeyArn: "arn:aws:kms:us-east-1:123456789012:key/055efbb4-xmpl-4336-ba9c-538c7d31f599"
    ...
```

若要能夠在 [GetEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_GetEventSourceMapping.html) 或 [DeleteEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_DeleteEventSourceMapping.html) API 呼叫中以純文字檢視加密的篩選條件，必須具備 `kms:Decrypt` 許可。

自 2024 年 8 月 6 日起，如果您的函式未使用事件篩選功能，則 [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html)、[UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) 與 [DeleteEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_DeleteEventSourceMapping.html) 等 API 呼叫的 AWS CloudTrail 日誌中，將不再顯示 `FilterCriteria` 欄位。如果您的函數使用事件篩選，`FilterCriteria` 欄位會顯示為空白 (`{}`)。如果您具有正確 KMS 金鑰的 `kms:Decrypt` 許可，仍然可以在 [GetEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_GetEventSourceMapping.html) API 呼叫的回應中以純文字檢視篩選條件。

### Create/Update/DeleteEventSourceMapping 呼叫的 CloudTrail 日誌項目範例
<a name="filter-criteria-encryption-cloudtrail"></a>

在 CreateEventSourceMapping 呼叫的下列 AWS CloudTrail 範例日誌項目中， `FilterCriteria` 會顯示為空白 (`{}`)，因為函數使用事件篩選。即使 `FilterCriteria` 物件包含函數正在使用的有效篩選條件，也是如此。如果函數不使用事件篩選，CloudTrail 絕對不會在日誌項目中顯示 `FilterCriteria` 欄位。

```
{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "AROA123456789EXAMPLE:userid1",
        "arn": "arn:aws:sts::123456789012:assumed-role/Example/example-role",
        "accountId": "123456789012",
        "accessKeyId": "ASIAIOSFODNN7EXAMPLE",
        "sessionContext": {
            "sessionIssuer": {
                "type": "Role",
                "principalId": "AROA987654321EXAMPLE",
                "arn": "arn:aws:iam::123456789012:role/User1",
                "accountId": "123456789012",
                "userName": "User1"
            },
            "webIdFederationData": {},
            "attributes": {
                "creationDate": "2024-05-09T20:35:01Z",
                "mfaAuthenticated": "false"
            }
        },
        "invokedBy": "AWS Internal"
    },
    "eventTime": "2024-05-09T21:05:41Z",
    "eventSource": "lambda.amazonaws.com",
    "eventName": "CreateEventSourceMapping20150331",
    "awsRegion": "us-east-2",
    "sourceIPAddress": "AWS Internal",
    "userAgent": "AWS Internal",
    "requestParameters": {
        "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:example-queue",
        "functionName": "example-function",
        "enabled": true,
        "batchSize": 10,
        "filterCriteria": {},
        "kMSKeyArn": "arn:aws:kms:us-east-2:123456789012:key/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111",
        "scalingConfig": {},
        "maximumBatchingWindowInSeconds": 0,
        "sourceAccessConfigurations": []
    },
    "responseElements": {
        "uUID": "a1b2c3d4-5678-90ab-cdef-EXAMPLEaaaaa",
        "batchSize": 10,
        "maximumBatchingWindowInSeconds": 0,
        "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:example-queue",
        "filterCriteria": {},
        "kMSKeyArn": "arn:aws:kms:us-east-2:123456789012:key/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111",
        "functionArn": "arn:aws:lambda:us-east-2:123456789012:function:example-function",
        "lastModified": "May 9, 2024, 9:05:41 PM",
        "state": "Creating",
        "stateTransitionReason": "USER_INITIATED",
        "functionResponseTypes": [],
        "eventSourceMappingArn": "arn:aws:lambda:us-east-2:123456789012:event-source-mapping:a1b2c3d4-5678-90ab-cdef-EXAMPLEbbbbb"
    },
    "requestID": "a1b2c3d4-5678-90ab-cdef-EXAMPLE33333",
    "eventID": "a1b2c3d4-5678-90ab-cdef-EXAMPLE22222",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "123456789012",
    "eventCategory": "Management",
    "sessionCredentialFromConsole": "true"
}
```

## 使用具有不同 的篩選條件 AWS 服務
<a name="filtering-by-service"></a>

不同類型的事件來源對其資料欄位使用不同的索引鍵值。若要篩選資料屬性，請務必在篩選條件模式中使用正確的索引鍵。下表提供每個支援的篩選金鑰 AWS 服務。


| AWS 服務 | 篩選索引鍵 | 
| --- | --- | 
| DynamoDB | dynamodb | 
| Kinesis | data | 
| Amazon MQ | data | 
| Amazon MSK | value | 
| 自我管理的 Apache Kafka | value | 
| Amazon SQS | body | 

下列各節提供不同類型事件來源的篩選模式範例。其還為每個支援之服務提供支援的傳入資料格式和篩選條件模式內文格式的定義。
+ [搭配 DynamoDB 事件來源使用事件篩選](with-ddb-filtering.md)
+ [搭配 Kinesis 事件來源使用事件篩選](with-kinesis-filtering.md)
+ [從 Amazon MQ 事件來源篩選事件](with-mq-filtering.md)
+ [從 Amazon MSK 和自我管理的 Apache Kafka 事件來源篩選事件](kafka-filtering.md)
+ [對 Amazon SQS 事件來源使用事件篩選](with-sqs-filtering.md)

# 在主控台中，測試 Lambda 函數。
<a name="testing-functions"></a>

您可以藉由使用測試事件調用函數，在主控台中測試您的 Lambda 函數。一個*測試事件*是函數的 JSON 輸入。如果您的函數不需要輸入，則該事件可以是空白的文件 `({})`。

當您在主控台執行測試時，Lambda 會與測試事件同步調用函數。函數執行期會將 JSON 事件轉換為物件，並將其傳遞給程式碼的處理常式方法以進行處理。

**建立測試事件**  
您必須先建立私有或可共用的測試事件，才能在主控台中測試。

## 使用測試事件調用函數
<a name="invoke-with-event"></a>

**若要測試函數**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇要測試的函數名稱。

1. 選擇**測試**標籤。

1. 在**測試事件**下，選擇**建立新事件**或**編輯已儲存事件**，然後選擇您要使用的已儲存事件。

1. (選擇性) - 選擇事件 JSON 的**範本**。

1. 選擇**測試**。

1. 若要檢閱測試結果，在 **Execution result** (執行結果) 下，展開 **Details** (詳細資訊)。

若要在不儲存測試事件的情況下調用您的函數，選擇**測試**，然後再儲存。這會建立一個未儲存的測試事件，而 Lambda 僅會在工作階段期間保留該事件。

對於 Node.js、Python 和 Ruby 執行時期，您也可以在**程式碼**索引標籤上存取現有的已儲存和未儲存的測試事件。使用**測試事件**區段來建立、編輯和執行測試。

## 建立私有測試事件
<a name="creating-private-events"></a>

只有事件建立者才能使用私有測試事件，且其不需要額外的許可即可使用。每個函數您可以建立並儲存最多 10 個私有測試事件。

**若要建立私有測試事件**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇要測試的函數名稱。

1. 選擇**測試**標籤。

1. 在 **Test event** (測試事件) 下，執行以下動作：

   1. 選擇 **Template** (範本)。

   1. 輸入該測試的 **Name** (名稱)。

   1. 在文字輸入方塊中，輸入 JSON 測試事件。

   1. 在 **Event sharing settings** (事件共用設定) 下，選擇 **Private** (私有)。

1. 選擇**儲存變更**。

對於 Node.js、Python 和 Ruby 執行時期，您也可以在**程式碼**索引標籤上建立測試事件。使用**測試事件**區段來建立、編輯和執行測試。

## 建立可共用測試事件
<a name="creating-shareable-events"></a>

可共用的測試事件是您可以與相同 AWS 帳戶中的其他使用者共用的測試事件。您可以編輯其他使用者的可共用測試事件，並使用它們來調用您的函數。

Lambda 將可共用測試事件以結構描述的形式，儲存在名為 `lambda-testevent-schemas` 的 [Amazon EventBridge (CloudWatch Events) 結構描述登錄檔](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-schema-registry.html)中。由於 Lambda 利用此登錄檔來存放和呼叫您建立的可共用測試事件，我們建議您不要編輯此登錄檔或使用 `lambda-testevent-schemas` 名稱建立登錄檔。

若要查看、共用和編輯可共用測試事件，您必須具有以下所有[EventBridge (CloudWatch Events) 結構描述登錄檔 API 操作](https://docs.aws.amazon.com/eventbridge/latest/schema-reference/operations.html)的許可：
+ [https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname.html#CreateRegistry](https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname.html#CreateRegistry)
+ [https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname-schemas-name-schemaname.html#CreateSchema](https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname-schemas-name-schemaname.html#CreateSchema)
+ [https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname-schemas-name-schemaname.html#DeleteSchema](https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname-schemas-name-schemaname.html#DeleteSchema)
+ [https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname-schemas-name-schemaname-version-schemaversion.html#DeleteSchemaVersion](https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname-schemas-name-schemaname-version-schemaversion.html#DeleteSchemaVersion)
+ [https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname.html#DescribeRegistry](https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname.html#DescribeRegistry)
+ [https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname-schemas-name-schemaname.html#DescribeSchema](https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname-schemas-name-schemaname.html#DescribeSchema)
+ [https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-discover.html#GetDiscoveredSchema](https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-discover.html#GetDiscoveredSchema)
+ [https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname-schemas-name-schemaname-versions.html#ListSchemaVersions](https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname-schemas-name-schemaname-versions.html#ListSchemaVersions)
+ [https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname-schemas-name-schemaname.html#UpdateSchema](https://docs.aws.amazon.com/eventbridge/latest/schema-reference/v1-registries-name-registryname-schemas-name-schemaname.html#UpdateSchema)

請注意，儲存對可共用測試事件所做的編輯將覆蓋該事件。

如果您無法建立、編輯或查看可共用測試事件，請檢查您的帳戶是否具有執行這些操作所需要的許可。如果您擁有所需要的許可，但仍然無法存取可共用測試事件，請檢查任何可能會限制對 EventBridge (CloudWatch Events) 登錄檔的存取的[資源型政策](access-control-resource-based.md)。

**若要建立可共用測試事件**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇要測試的函數名稱。

1. 選擇**測試**標籤。

1. 在 **Test event** (測試事件) 下，執行以下動作：

   1. 選擇 **Template** (範本)。

   1. 輸入該測試的 **Name** (名稱)。

   1. 在文字輸入方塊中，輸入 JSON 測試事件。

   1. 在 **Event sharing settings** (事件共用設定) 下，選擇 **Shareable** (可共用)。

1. 選擇**儲存變更**。

**搭配 使用可共用的測試事件 AWS Serverless Application Model。**  
您可以使用 AWS SAM 叫用可共用的測試事件。請參閱《[AWS Serverless Application Model 開發人員指南](https://docs.aws.amazon.com//serverless-application-model/latest/developerguide/using-sam-cli-remote-test-event.html)》中的 [https://docs.aws.amazon.com//serverless-application-model/latest/developerguide/using-sam-cli-remote-test-event.html](https://docs.aws.amazon.com//serverless-application-model/latest/developerguide/using-sam-cli-remote-test-event.html)。

## 刪除可共用測試事件結構描述
<a name="deleting-test-schemas"></a>

當您刪除可共用測試事件時，Lambda 會將其從 `lambda-testevent-schemas` 登錄檔中移除。如果您是從登錄檔移除最後一個可共用測試事件，則 Lambda 會刪除登錄檔。

如果刪除函數，Lambda 不會刪除任何關聯的可共用測試事件結構描述。您必須從 [EventBridge (CloudWatch Events) 主控台](https://console.aws.amazon.com/events)手動清理這些資源。

# Lambda 函數狀態
<a name="functions-states"></a>

所有 Lambda 函式的函式組態中都包含一個[狀態](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html#lambda-GetFunctionConfiguration-response-State)欄位，用於指示函式何時準備就緒可供調用。`State` 會提供函式目前狀態的相關資訊，包括是否可以成功調用函式。函數狀態不會變更函數叫用的行為或函數執行程式碼的方式。

**注意**  
[SnapStart](snapstart.md) 函式的函式狀態定義略有不同。如需詳細資訊，請參閱[Lambda SnapStart 和函數狀態](snapstart-activate.md#snapstart-function-states)。

在許多情況下，DynamoDB 資料表是在調用間隔期間保留狀態的理想方式，因為其提供低延遲資料存取，並且可以隨著 Lambda 服務擴展。如果您使用 [Amazon EFS for Lambda](https://aws.amazon.com/blogs/compute/using-amazon-efs-for-aws-lambda-in-your-serverless-applications/)，也可以將資料儲存在此服務中，這樣也可以實現對檔案系統儲存的低延遲存取。

函數狀態包括：
+ `Pending` – Lambda 建立函數之後，會將狀態設定為待定中。處於待定狀態時，Lambda 會嘗試建立或設定函數的資源，例如 VPC 或 EFS 資源。Lambda 不會叫用待定狀態期間的函數。在函數上操作的任何叫用或其他 API 操作都會失敗。
+ `Active` – Lambda 完成資源組態和佈建之後，您的函數會轉換為啟用中狀態。只有啟用中的函數才能成功叫用。
+ `Failed` – 表示資源配置或佈建發生錯誤。當函數建立失敗時，Lambda 會將函數狀態設定為失敗，而且您必須刪除並重新建立函數。
+ `Inactive` – 當函數空閒足夠長的時間，以至於 Lambda 回收為其配置的外部資源時，該函數將變為非啟用狀態。當您嘗試叫用非啟用中的函數，叫用會失敗而 Lambda 會將函數設定為待定狀態，直到重新建立函數資源為止。如果 Lambda 無法重新建立資源，則函數會返回到非啟用狀態。您可能需要解決錯誤後再重新部署函式，將其還原為作用中狀態。

如果您是使用 SDK 型自動化工作流程或是直接呼叫 Lambda 的服務 API，請務必在調用之前檢查函數的狀態，以驗證其是否處於作用中狀態。您可以使用 Lambda API 動作 [GetFunction](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunction.html) 來完成此動作，或者透過使用 [AWS SDK for Java 2.0](https://github.com/aws/aws-sdk-java-v2) 配置等候程序。

```
aws lambda get-function --function-name my-function --query 'Configuration.[State, LastUpdateStatus]'
```

您應該會看到下列輸出：

```
[
 "Active",
 "Successful" 
]
```

當函數的建立處於待定狀態時，下列作業會失敗：
+ [Invoke](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)
+ [UpdateFunctionCode](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionCode.html)
+ [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html)
+ [PublishVersion](https://docs.aws.amazon.com/lambda/latest/api/API_PublishVersion.html)

## 更新期間的函式狀態
<a name="functions-states-updating"></a>

Lambda 提供兩種更新函式的操作：
+ [UpdateFunctionCode](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionCode.html)：更新函式的部署套件
+ [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html)：更新函式的組態

Lambda 使用 [LastUpdateStatus](https://docs.aws.amazon.com/lambda/latest/api/API_FunctionConfiguration.html#lambda-Type-FunctionConfiguration-LastUpdateStatus) 屬性來追蹤這些更新操作的進度。當更新正在進行時 (即 `"LastUpdateStatus": "InProgress"`)：
+ 函式的[狀態](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html#lambda-GetFunctionConfiguration-response-State)會保持 `Active`。
+ 在更新完成之前，調用仍會使用函式的舊版程式碼與組態。
+ 下列操作會失敗：
  + [UpdateFunctionCode](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionCode.html)
  + [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html)
  + [PublishVersion](https://docs.aws.amazon.com/lambda/latest/api/API_PublishVersion.html)
  + [TagResource](https://docs.aws.amazon.com/lambda/latest/api/API_TagResource.html)

當更新失敗時 （當 時`"LastUpdateStatus": "Failed"`)：
+ 函式的[狀態](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html#lambda-GetFunctionConfiguration-response-State)會保持 `Active`。
+ 調用會繼續使用函數先前的程式碼和組態。

**Example GetFunctionConfiguration 回應**  
下列範例展示正在更新的函式執行 [GetFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html) 請求所傳回的結果。  

```
{
    "FunctionName": "my-function",
    "FunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
    "Runtime": "nodejs24.x",
    "VpcConfig": {
        "SubnetIds": [
            "subnet-071f712345678e7c8",
            "subnet-07fd123456788a036",
            "subnet-0804f77612345cacf"
        ],
        "SecurityGroupIds": [
            "sg-085912345678492fb"
        ],
        "VpcId": "vpc-08e1234569e011e83"
    },
    "State": "Active",
    "LastUpdateStatus": "InProgress",
    ...
}
```

# 了解 Lambda 中的重試行為
<a name="invocation-retries"></a>

直接叫用函數時，您可以決定處理函數程式碼相關錯誤的策略。Lambda 不會自動代您重試這類錯誤。若要進行重試，您可以手動重新叫用函數、將失敗的事件傳送到佇列進行偵錯，或忽略錯誤。您函式的程式碼可能已完全執行、部分執行或完全未執行。如果您重試，請確保您函式的程式碼可處理相同的事件很多次，而不會導致重複的交易或其他不想要的副作用。

當您間接叫用函式時，您需要留意叫用端的重試行為及任何遭遇請求的服務。這包括以下案例。
+ **Asynchronous invocation** (非同步叫用) - Lambda 會重試函數錯誤兩次。如果函數沒有足夠的容量來處理所有傳入的請求，事件可能在佇列中等待數小時才會傳送到函數。您可以在函式上設定無效信件佇列，以擷取未成功處理的事件。如需更多詳細資訊，請參閱 [新增無效字母佇列](invocation-async-retain-records.md#invocation-dlq)。
+ **Event source mappings** (事件來源映射) - 從串流中讀取的事件來源映射會重試整批項目。在錯誤解決或項目過期前，重複的錯誤會阻礙受影響碎片的處理。若要偵測已停滯的碎片，您可以監控[反覆運算器年齡](monitoring-metrics.md)指標。

  對於從佇列讀取的事件來源映射，您可藉由設定來源佇列的可見性逾時和再驅動政策，決定重試之間的時間長度和失敗事件的目的地。如需詳細資訊，請參閱 [Lambda 如何處理來自串流和佇列式事件來源的記錄](invocation-eventsourcemapping.md) 和 [使用來自其他服務的事件叫用 Lambda AWS](lambda-services.md) 下的服務特定主題。
+ **AWS 服務** – AWS 服務可以[同步](invocation-sync.md)或非同步地調用您的函式。對於同步叫用，服務會決定是否要重試。例如，如果 Lambda 函數傳回 `TemporaryFailure` 回應代碼，則 Amazon S3 批次操作會重試該操作。代理來自上游使用者或用戶端之請求的服務可能有重試策略，或可能會將錯誤回應轉送回請求者。例如，API Gateway 一律會將錯誤回應轉送回請求者。

  對於非同步調用，無論調用來源為何，重試邏輯都相同。依預設，Lambda 最多會重試失敗的非同步調用兩次。如需更多詳細資訊，請參閱 [Lambda 如何處理非同步調用的錯誤和重試](invocation-async-error-handling.md)。
+ **Other accounts and clients** (其他帳戶和用戶端) - 當您授與其他帳戶的存取權時，您可使用[以資源為基礎的政策](access-control-resource-based.md)來限制其可設定的服務或資源，以叫用您的函數。為了保護您的函數以免過載，請考慮透過 [Amazon API Gateway](services-apigateway.md) 在您的函數前面放置 API 層。

為了協助您處理 Lambda 應用程式中的錯誤，Lambda 會與 Amazon CloudWatch 和 AWS X-Ray 等服務整合。您可以使用日誌、指標、警示和追蹤的組合，快速偵測及識別您的函式程式碼、API 或其他支援您應用程式的資源中的問題。如需更多詳細資訊，請參閱 [監控、偵錯與疑難排解 Lambda 函式](lambda-monitoring.md)。

# 使用 Lambda 遞迴迴圈偵測功能防止無限迴圈
<a name="invocation-recursion"></a>

當您將 Lambda 函數設定為輸出至調用該函數的相同服務或資源時，就可以建立無限遞迴迴圈。例如，Lambda 函數可能會將訊息寫入 Amazon Simple Queue Service (Amazon SQS) 佇列，然後調用相同的函數。此調用會導致函數將另一則訊息寫入佇列，進而再次調用函數。

意外的遞迴迴圈可能會導致意外費用向您的 收費 AWS 帳戶。迴圈也可能導致 Lambda [擴展](lambda-concurrency.md)和使用您帳戶的所有可用並行處理。為了減少意外迴圈的影響，Lambda 可在特定類型的遞迴迴圈發生後不久偵測到它們。當 Lambda 偵測到遞迴迴圈時，預設會停止調用函數並通知您。如果您的設計刻意使用遞迴模式，您可以變更函數的預設組態，允許以遞迴方式調用它。如需詳細資訊，請參閱[允許 Lambda 函數在遞迴迴圈中執行](#invocation-recursion-disable)。

**Topics**
+ [

## 了解遞迴迴圈偵測
](#invocation-recursion-concepts)
+ [

## 支援的 AWS 服務 和 SDKs
](#invocation-recursion-supported)
+ [

## 遞迴迴圈通知
](#invocation-recursion-monitoring)
+ [

## 回應遞迴迴圈偵測通知
](#invocation-recursion-responding)
+ [

## 允許 Lambda 函數在遞迴迴圈中執行
](#invocation-recursion-disable)
+ [

## 支援 Lambda 遞迴迴圈偵測功能的區域
](#invocation-recursion-regions)

## 了解遞迴迴圈偵測
<a name="invocation-recursion-concepts"></a>

Lambda 中的遞迴迴圈偵測透過追蹤事件來運作。Lambda 是事件驅動型運算服務，可在特定事件發生時執行函數程式碼。例如，將項目新增至 Amazon SQS 佇列或 Amazon Simple Notiﬁcation Service (Amazon SNS) 主題時。Lambda 會將事件以 JSON 物件的形式傳遞至函數，其中包含系統狀態中的變更資訊。當事件導致函數執行時，這稱為*調用*。

若要偵測遞迴迴圈，Lambda 會使用 [AWS X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html) 追蹤標頭。當[支援遞迴迴圈偵測的AWS 服務](#invocation-recursion-supportedservices) 將事件傳送至 Lambda 時，這些事件會自動使用中繼資料進行註解。當您的 Lambda 函數 AWS 服務 使用支援的 [AWS SDK 版本將其中一個事件寫入到另一個支援的事件時](#invocation-recursion-supportedsdks)，它會更新此中繼資料。更新後的中繼資料包含事件調用函數的次數計數。

**注意**  
您不需要啟用 X-Ray 作用中追蹤，即可使用此功能。依預設，所有 AWS 客戶都會開啟遞迴迴路偵測。使用此功能無需支付任何費用。

*請求鏈*是由相同觸發事件引起的一系列 Lambda 調用。例如，假設 Amazon SQS 佇列調用 Lambda 函數。然後，Lambda 函數會將已處理的事件傳回相同的 Amazon SQS 佇列，然後再次調用函數。在此範例中，函數的每次調用都屬於相同的請求鏈。

如果您的函數在相同的請求鏈中被調用大約 16 次，則 Lambda 會自動停止該請求鏈中的下一個函數調用並通知您。如果函數設有多個觸發條件，來自其他觸發條件的調用不會受影響。

**注意**  
即使來源佇列再驅動政策的 `maxReceiveCount` 設定高於 16，Lambda 遞迴保護也不會阻止 Amazon SQS 在偵測到遞迴迴圈並終止後重試訊息。當 Lambda 偵測到遞迴迴圈並捨棄後續調用時，會將 `RecursiveInvocationException` 傳回至事件來源映射。這會增加訊息上的 `receiveCount` 值。Lambda 會繼續重試訊息，並繼續封鎖函數調用，直至 Amazon SQS 判斷超過 `maxReceiveCount`，並將訊息傳送至設定的無效字母佇列。

如果您為函數設定了[故障時的目的地](invocation-async-retain-records.md#invocation-async-destinations)或[無效字母佇列](invocation-async-retain-records.md#invocation-dlq)，則 Lambda 也會將事件從已停止的調用中傳送至目的地或無效字母佇列。為函式設定目的地或無效字母佇列時，請勿使用函式也在使用的事件觸發程序或事件來源映射。若將事件傳送至調用函式的同一個資源，則可能會建立另一個遞迴迴圈，且此迴圈同樣會被終止。若關閉遞迴迴圈偵測功能，此類迴圈不會被終止。

## 支援的 AWS 服務 和 SDKs
<a name="invocation-recursion-supported"></a>

Lambda 只能偵測包含特定支援的遞迴迴圈 AWS 服務。若要偵測遞迴迴圈，您的函數也必須使用其中一個支援的 AWS SDKs。

### 支援的 AWS 服務
<a name="invocation-recursion-supportedservices"></a>

Lambda 目前可偵測函數、Amazon SQS、Amazon S3 和 Amazon SNS 之間的遞迴迴圈。Lambda 也會偵測僅由 Lambda 函數組成的迴圈，這些函數可以同步或非同步相互調用。下圖顯示 Lambda 可以偵測的一些迴圈範例：

![\[Lambda 函數、Amazon SNS、Amazon S3 和 Amazon SQS 佇列之間的遞迴迴圈圖示。\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/RunawayWorkloadDetected_v3.png)


當 Amazon DynamoDB AWS 服務 等其他 形成迴圈的一部分時，Lambda 目前無法偵測並停止它。

由於 Lambda 目前僅偵測涉及 Amazon SQS、Amazon S3 和 Amazon SNS 的遞迴迴圈，因此涉及其他 的迴圈仍可能導致 Lambda 函數 AWS 服務 意外使用。

為了防止向您的 收取意外費用 AWS 帳戶，建議您設定 [Amazon CloudWatch 警示](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)，以提醒您不尋常的使用模式。例如，可以設定 CloudWatch，以便在 Lambda 函數並行處理或調用出現峰值時通知您。也可以設定[帳單警示](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_cloudwatch.html)，當帳戶中的支出超過指定的閾值時通知您。或者，可以使用 [AWS Cost Anomaly Detection](https://docs.aws.amazon.com/cost-management/latest/userguide/manage-ad.html) 來提醒您不尋常的帳單模式。

### 支援的 AWS SDKs
<a name="invocation-recursion-supportedsdks"></a>

若要讓 Lambda 偵測遞迴迴圈，函數必須使用下列其中一個 SDK 版本或更高版本：


| 執行時期 | 最低必要 AWS SDK 版本 | 
| --- | --- | 
|  Node.js  |  2.1147.0 (SDK 版本 2) 3.105.0 (SDK 版本 3)  | 
|  Python  |  1.24.46 (boto3) 1.27.46 (botocore)  | 
|  Java 8 和 Java 11  |  2.17.135  | 
|  Java 17  |  2.20.81  | 
|  Java 21  |  2.21.24  | 
|  .NET  |  3.7.293.0  | 
|  Ruby  |  3.134.0  | 
|  PHP  |  3.232.0  | 
|  Go  |  V2 SDK 1.57.0  | 

Python 和 Node.js 等某些 Lambda 執行時間包含 AWS SDK 的版本。如果函數執行期中包含的 SDK 版本低於所需的最低版本，則可以將支援的 SDK 版本新增到函數的部署套件。您也可以使用 [Lambda 層](chapter-layers.md)將支援的 SDK 版本新增至函數。如需每個 Lambda 執行期包含的 SDK 清單，請參閱 [Lambda 執行期](lambda-runtimes.md)。

## 遞迴迴圈通知
<a name="invocation-recursion-monitoring"></a>

當 Lambda 停止遞迴迴圈時，您會透過 [Health 儀板表](https://aws.amazon.com/premiumsupport/technology/aws-health-dashboard/) 和電子郵件接收通知。也可以使用 CloudWatch 指標來監控 Lambda 已停止的遞迴調用次數。

### Health 儀板表 通知
<a name="invocation-recursion-phd"></a>

當 Lambda 停止遞迴調用時， 會在**您的帳戶運作**狀態頁面的[開啟和最近問題](https://health.aws.amazon.com/health/home#/account/dashboard/open-issues)下 Health 儀板表 顯示通知。請注意，在 Lambda 停止遞迴調用後，可能需要 3.5 小時才會顯示此通知。如需有關在 中檢視帳戶事件的詳細資訊 Health 儀板表，請參閱《[AWS 運作狀態使用者指南》中的運作狀態儀表板 – 您的帳戶運作狀態入門](https://docs.aws.amazon.com/health/latest/ug/getting-started-health-dashboard.html)。 *AWS *

### 電子郵件提醒
<a name="invocation-recursion-email"></a>

當 Lambda 第一次停止函數的遞迴調用時，會傳送電子郵件提醒給您。對於 AWS 帳戶中的每個函數，Lambda 每 24 小時最多傳送一封電子郵件。Lambda 傳送電子郵件通知後，即使 Lambda 停止函數的進一步遞迴調用，在接下來的 24 小時也不會再收到該函數的任何電子郵件。請注意，在 Lambda 停止遞迴調用後，可能需要 3.5 小時才會收到此電子郵件提醒。

Lambda 會傳送遞迴迴圈電子郵件提醒給您 AWS 帳戶的主要帳戶聯絡人和替代操作聯絡人。如需有關檢視或更新帳戶中電子郵件地址的資訊，請參閱《AWS 一般參考》**中的[更新聯絡資訊](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-update-contact.html)。

### Amazon CloudWatch 指標
<a name="invocation-recursion-cloudwatch"></a>

[CloudWatch 指標](monitoring-metrics-types.md)`RecursiveInvocationsDropped`會記錄 Lambda 已停止的函數調用次數，因為您的函數已在單一請求鏈中調用大約 16 次。Lambda 會在停止遞迴調用時立即發出此指標。若要檢視此指標，請按照[在 CloudWatch 主控台上檢視指標](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-metrics.html#monitoring-metrics-console)的說明進行操作，並選擇指標 `RecursiveInvocationsDropped`。

## 回應遞迴迴圈偵測通知
<a name="invocation-recursion-responding"></a>

當函數被同一觸發事件調用大約 16 次時，Lambda 會停止該事件的下一個函數調用，以中斷遞迴迴圈。若要防止 Lambda 已中斷的遞迴迴圈再次發生，請執行下列動作：
+ 將函數的可用[並行處理](lambda-concurrency.md)降為零，這會限制所有將來的調用。
+ 移除或停用正在調用函數的觸發條件或事件來源映射。
+ 識別並修正程式碼瑕疵，將事件寫回叫用函數 AWS 的資源。當您使用變數來定義函數的事件來源和目標時，就會出現常見的缺陷來源。檢查兩個變數沒有使用相同的值。

此外，如果 Lambda 函數的事件來源是 Amazon SQS 佇列，則請考慮在來源佇列上[設定無效字母佇列](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-dead-letter-queue.html)。

**注意**  
請確定在來源佇列上設定無效字母佇列，而不是在 Lambda 函數上。您在函數上設定的無效字母佇列用於佇列的[非同步調用函數](invocation-async.md)，而不是事件來源佇列。

如果事件來源是 Amazon SNS 主題，則請考慮為函數新增[故障時的目的地](invocation-async-retain-records.md#invocation-async-destinations)。

**將函數的可用並行處理降為零 (主控台)**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇 函數的名稱。

1. 選擇**調節**。

1. 在**調節函數**對話方塊中，選擇**確認**。

**若要移除函數的觸發條件或事件來源映射 (主控台)**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇 函數的名稱。

1. 選擇**組態**索引標籤，然後**觸發條件**。

1. 在**觸發條件**下，選取要刪除的觸發條件或事件來源映射，然後選擇**刪除**。

1. 在**刪除觸發條件**對話方塊中，選擇**刪除**。

**若要停用函數的事件來源映射 (AWS CLI)**

1. 若要尋找您要停用之事件來源映射的 UUID，請執行 AWS Command Line Interface (AWS CLI) [list-event-source-mappings](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/list-event-source-mappings.html) 命令。

   ```
   aws lambda list-event-source-mappings
   ```

1. 若要停用事件來源映射，請執行 following AWS CLI [update-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-event-source-mapping.html) 命令。

   ```
   aws lambda update-event-source-mapping --function-name MyFunction \
   --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 --no-enabled
   ```

## 允許 Lambda 函數在遞迴迴圈中執行
<a name="invocation-recursion-disable"></a>

如果您的設計刻意使用遞迴迴圈，您可以設定 Lambda 函數，以允許以遞迴方式調用它。我們建議您避免在設計中使用遞迴迴圈。實作錯誤可能會導致使用您所有 AWS 帳戶可用的並行進行遞迴調用，以及向您的 帳戶收取意外費用。

**重要**  
如果您使用遞迴迴圈，請謹慎處理。實作最佳實務防護措施，將實作錯誤的風險降至最低。若要進一步了解使用遞迴模式的最佳實務，請參閱 Serverless Land 中的 [Recursive patterns that cause run-away Lambda functions](https://serverlessland.com/content/service/lambda/guides/aws-lambda-operator-guide/recursive-runaway)。

您可以設定函數，以允許使用 Lambda 主控台、 AWS Command Line Interface (AWS CLI) 和 [PutFunctionRecursionConfig](https://docs.aws.amazon.com//lambda/latest/api/API_PutFunctionRecursionConfig.html) API 進行遞迴迴圈。您也可以在 AWS SAM 和 中設定函數的遞迴迴圈偵測設定 CloudFormation。

依預設，Lambda 會偵測並終止遞迴迴圈。除非設計刻意使用遞迴迴圈，否則建議不要變更函數的預設組態。

請注意，當您設定函數以允許遞迴迴圈時，不會發出 [CloudWatch 指標](monitoring-metrics-types.md#invocation-metrics) `RecursiveInvocationsDropped`。

------
#### [ Console ]

**若要允許函數在遞迴迴圈中執行 (主控台)**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇函數的名稱以開啟函數詳細資訊頁面。

1. 選擇**組態**標籤，然後選擇**並行和遞迴偵測**。

1. 除了**遞迴迴圈偵測**，選擇**編輯**。

1. 選取**允許遞迴迴圈**。

1. 選擇**儲存**。

------
#### [ AWS CLI ]

您可以使用 [PutFunctionRecursionConfig](https://docs.aws.amazon.com/lambda/latest/api/API_PutFunctionRecursionConfig.html) API 來允許在遞迴迴圈中調用函數。為遞迴迴圈參數指定 `Allow`。例如，您可以使用 `put-function-recursion-config` AWS CLI 命令呼叫此 API：

```
aws lambda put-function-recursion-config --function-name yourFunctionName --recursive-loop Allow
```

------

您可以將函數的組態變更回預設設定，以便 Lambda 在偵測到遞迴迴圈時將其終止。使用 Lambda 主控台或 AWS CLI編輯函數的組態。

------
#### [ Console ]

**若要設定函數以終止遞迴迴圈 (主控台)**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇函數的名稱以開啟函數詳細資訊頁面。

1. 選擇**組態**標籤，然後選擇**並行和遞迴偵測**。

1. 除了**遞迴迴圈偵測**，選擇**編輯**。

1. 選取**終止遞迴迴圈**。

1. 選擇**儲存**。

------
#### [ AWS CLI ]

您可以使用 [PutFunctionRecursionConfig](https://docs.aws.amazon.com/lambda/latest/api/API_PutFunctionRecursionConfig.html) API 來設定函數，以便 Lambda 在偵測到遞迴迴圈時將其終止。為遞迴迴圈參數指定 `Terminate`。例如，您可以使用 `put-function-recursion-config` AWS CLI 命令呼叫此 API：

```
aws lambda put-function-recursion-config --function-name yourFunctionName --recursive-loop Terminate
```

------

## 支援 Lambda 遞迴迴圈偵測功能的區域
<a name="invocation-recursion-regions"></a>

所有[商業區域](https://docs.aws.amazon.com/general/latest/gr/glos-chap.html#region)都支援 Lambda 遞迴迴圈偵測，但墨西哥 (中部) 與亞太區域 (紐西蘭) 除外。

# 建立及管理 Lambda 函數 URL
<a name="urls-configuration"></a>

函數 URL 是 Lambda 函數專用的 HTTP(S) 端點。您可以透過 Lambda 主控台或 Lambda API 建立及設定函數 URL。

**提示**  
Lambda 提供兩種透過 HTTP 端點調用函數的方式：函數 URL 與 Amazon API Gateway。如果不確定哪種方法最適合自己的使用案例，請參閱[選取一種使用 HTTP 請求調用 Lambda 函數的方法](furls-http-invoke-decision.md)。

當您建立函數 URL 時，Lambda 會自動為您產生不重複的 URL 端點。函數 URL 一旦建立，其 URL 端點便永遠不會變更。函數 URL 端點的格式如下：

```
https://<url-id>.lambda-url.<region>.on.aws
```

**注意**  
下列 不支援函數 URLs AWS 區域：亞太區域 （海德拉巴） (`ap-south-2`)、亞太區域 （墨爾本） (`ap-southeast-4`)、亞太區域 （馬來西亞） (`ap-southeast-5`)、亞太區域 （紐西蘭） (`ap-southeast-6`)、亞太區域 （泰國） (`ap-southeast-7`)、亞太區域 （台北） (`ap-east-2`)、加拿大西部 （卡加利） (`ca-west-1`)、歐洲 （西班牙） (`eu-south-2`)、歐洲 （蘇黎世） (`eu-central-2`)、以色列 （特拉維夫） (`il-central-1`) 和中東 （阿拉伯聯合大公國） ()`me-central-1`)。

函數 URL 可支援雙堆疊，能同時支援 IPv4 和 IPv6。為函數設定函數 URL 後，您可以利用 Web 瀏覽器、curl、Postman 或任何 HTTP 用戶端，透過 HTTP(S) 端點呼叫函數。

**注意**  
您只能透過公有網際網路存取您的函數 URL。雖然 Lambda 函數確實支援 AWS PrivateLink，但函數 URL 不支援。

Lambda 函數 URL 使用[以資源為基礎的政策](access-control-resource-based.md)，妥善控管安全性和存取權。函數 URL 也支援跨來源資源共用 (CORS) 組態選項。

您可以將函數 URL 套用至任何函數別名或未發佈的`$LATEST`函數版本。函數 URL 無法新增至其他任何函數版本。

下一節說明如何使用 Lambda 主控台和 CloudFormation 範本建立 AWS CLI和管理函數 URL

**Topics**
+ [

## 建立函數 URL (主控台)
](#create-url-console)
+ [

## 建立函數 URL (AWS CLI)
](#create-url-cli)
+ [

## 將函數 URL 新增至 CloudFormation 範本
](#urls-cfn)
+ [

## 跨來源資源共享 (CORS)
](#urls-cors)
+ [

## 調節函數 URL
](#urls-throttling)
+ [

## 停用函數 URL
](#urls-deactivating)
+ [

## 刪除函數 URL
](#w2aac39c81c53)
+ [

# 控制對 Lambda 函數 URL 的存取
](urls-auth.md)
+ [

# 呼叫 Lambda 函數 URL
](urls-invocation.md)
+ [

# 監控 Lambda 函數 URL
](urls-monitoring.md)
+ [

# 選取一種使用 HTTP 請求調用 Lambda 函數的方法
](furls-http-invoke-decision.md)
+ [

# 教學課程：使用 Lambda 函式 URL 建立 Webhook 端點
](urls-webhook-tutorial.md)

## 建立函數 URL (主控台)
<a name="create-url-console"></a>

請遵循下列步驟，使用主控台建立函數 URL。

### 為現有函數建立函數 URL
<a name="create-url-existing-function"></a>

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇您要為其建立函數 URL 的函數名稱。

1. 選擇 **Configuration** (組態) 標籤，然後選擇 **Function URL** (函數 URL)。

1. 選擇 **Create function URL** (建立函數 URL)。

1. 為 **Auth type** (驗證類型) 選擇 **AWS\$1IAM** 或 **NONE** (無)。如需函數 URL 身分驗證的詳細資訊，請參閱[存取控制](urls-auth.md)。

1. (選用) 選取 **Configure cross-origin resource sharing (CORS)** (設定跨來源資源共享 (CORS))，然後完成函數 URL 的 CORS 設定。如需 CORS 的詳細資訊，請參閱「[跨來源資源共享 (CORS)](#urls-cors)」。

1. 選擇**儲存**。

這樣即可為 `$LATEST` 未發佈版本的函數建立函數 URL。函數 URL 會顯示於主控台的 **Function overview** (函數概觀) 區段。

### 為現有別名建立函數 URL
<a name="create-url-existing-alias"></a>

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 找到您要為其建立函數 URL 的函數別名，選擇其函數名稱。

1. 選擇 **Aliases** (別名) 標籤，接著找到您要為其建立函數 URL 的函數別名，選擇該別名的名稱。

1. 選擇 **Configuration** (組態) 標籤，然後選擇 **Function URL** (函數 URL)。

1. 選擇 **Create function URL** (建立函數 URL)。

1. 為 **Auth type** (驗證類型) 選擇 **AWS\$1IAM** 或 **NONE** (無)。如需函數 URL 身分驗證的詳細資訊，請參閱[存取控制](urls-auth.md)。

1. (選用) 選取 **Configure cross-origin resource sharing (CORS)** (設定跨來源資源共享 (CORS))，然後完成函數 URL 的 CORS 設定。如需 CORS 的詳細資訊，請參閱「[跨來源資源共享 (CORS)](#urls-cors)」。

1. 選擇**儲存**。

這樣即可為函數別名建立函數 URL。函數 URL 會顯示於主控台中別名的 **Function overview** (函數概觀) 區段。

### 使用函數 URL 建立新函數
<a name="create-url-new-function"></a>

**建立具有函數 URL 的新函數 (主控台)**

1. 開啟 Lambda 主控台中的 [函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇**建立函數**。

1. 在**基本資訊**下，請執行下列動作：

   1. 為 **Function name** (函數名稱) 輸入您函數的名稱，例如 **my-function**。

   1. 針對**執行時間**，選擇您偏好的語言執行時間，例如 **Node.js 24**。

   1. 為 **Architecture** (架構) 選擇 **x86\$164** 或 **arm64**。

   1. 展開 **Permissions** (許可)，接著選擇建立新的執行角色或使用現有角色。

1. 展開 **Advanced settings** (進階設定)，然後選取 **Function URL** (函數 URL)。

1. 為 **Auth type** (驗證類型) 選擇 **AWS\$1IAM** 或 **NONE** (無)。如需函數 URL 身分驗證的詳細資訊，請參閱[存取控制](urls-auth.md)。

1. (選用) 選取 **Configure cross-origin resource sharing (CORS)** (設定跨來源資源共享 (CORS))。只要您在建立函數的過程中選取此選項，在預設情形下，您的函數 URL 就能允許所有來源的請求。建立函數後，您可以編輯函數 URL 的 CORS 設定。如需 CORS 的詳細資訊，請參閱「[跨來源資源共享 (CORS)](#urls-cors)」。

1. 選擇**建立函數**。

這樣即可為 `$LATEST` 未發佈版本的函數建立具有函數 URL 的新函數。函數 URL 會顯示於主控台的 **Function overview** (函數概觀) 區段。

## 建立函數 URL (AWS CLI)
<a name="create-url-cli"></a>

若要使用 AWS Command Line Interface (AWS CLI) 為現有的 Lambda 函數建立函數 URL，請執行下列命令：

```
aws lambda create-function-url-config \
    --function-name my-function \
    --qualifier prod \ // optional
    --auth-type AWS_IAM
    --cors-config {AllowOrigins="https://example.com"} // optional
```

這會將函數 URL 新增至函數 **my-function** 的 **prod** 限定詞。如需這些組態參數的詳細資訊，請參閱 API 參考資料中的 [CreateFunctionUrlConfig](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunctionUrlConfig.html)。

**注意**  
若要透過 建立函數 URL AWS CLI，函數必須已存在。

## 將函數 URL 新增至 CloudFormation 範本
<a name="urls-cfn"></a>

若要將 `AWS::Lambda::Url` 資源新增至 CloudFormation 範本，請使用下列語法：

### JSON
<a name="urls-cfn-json"></a>

```
{
  "Type" : "AWS::Lambda::Url",
  "Properties" : {
      "AuthType" : String,
      "Cors" : Cors,
      "Qualifier" : String,
      "TargetFunctionArn" : String
    }
}
```

### YAML
<a name="urls-cfn-yaml"></a>

```
Type: AWS::Lambda::Url
Properties: 
  AuthType: String
  Cors: 
    Cors
  Qualifier: String
  TargetFunctionArn: String
```

### Parameters
<a name="urls-cfn-params"></a>
+ (必要) `AuthType` – 定義函數 URL 的身分驗證類型。可能的值為 `AWS_IAM` 或 `NONE`。如果您希望只讓完成身分驗證的使用者存取，請設為 `AWS_IAM`。如要繞過 IAM 身分驗證，並允許任何使用者向您的函數提出請求，請設為 `NONE`。
+ (選用) `Cors` – 定義函數 URL 的 [CORS 設定](#urls-cors)。如要將 `Cors` 新增至 CloudFormation 中的 `AWS::Lambda::Url` 資源，請使用下列語法。

    
**Example AWS::Lambda::Url.Cors (JSON)**  

  ```
  {
    "AllowCredentials" : Boolean,
    "AllowHeaders" : [ String, ... ],
    "AllowMethods" : [ String, ... ],
    "AllowOrigins" : [ String, ... ],
    "ExposeHeaders" : [ String, ... ],
    "MaxAge" : Integer
  }
  ```  
**Example AWS::Lambda::Url.Cors (YAML)**  

  ```
    AllowCredentials: Boolean
    AllowHeaders: 
      - String
    AllowMethods: 
      - String
    AllowOrigins: 
      - String
    ExposeHeaders: 
      - String
    MaxAge: Integer
  ```
+ (選用) `Qualifier` – 別名名稱。
+ (必要) `TargetFunctionArn` - Lambda 函數的名稱或 Amazon Resource Name (ARN)。有效名稱的格式包括：
  + **函數名稱** – `my-function`
  + **函數 ARN** – `arn:aws:lambda:us-west-2:123456789012:function:my-function`
  + **部分 ARN** – `123456789012:function:my-function`

## 跨來源資源共享 (CORS)
<a name="urls-cors"></a>

如要定義不同來源存取您函數 URL 的方式，請使用[跨來源資源共享 (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)。如果您打算從其他網域呼叫函數 URL，建議您設定 CORS。Lambda 為函數 URL 支援以下 CORS 標頭。


| CORS 標頭 | CORS 組態屬性 | 範例值 | 
| --- | --- | --- | 
|  [ Access-Control-Allow-Origin](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin)  |  `AllowOrigins`  |  `*` (允許所有來源) `https://www.example.com` `http://localhost:60905`  | 
|  [ Access-Control-Allow-Methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods)  |  `AllowMethods`  |  `GET`, `POST`, `DELETE`, `*`  | 
|  [ Access-Control-Allow-Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers)  |  `AllowHeaders`  |  `Date`, `Keep-Alive`, `X-Custom-Header`  | 
|  [ Access-Control-Expose-Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers)  |  `ExposeHeaders`  |  `Date`, `Keep-Alive`, `X-Custom-Header`  | 
|  [ Access-Control-Allow-Credentials](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials)  |  `AllowCredentials`  |  `TRUE`  | 
|  [ Access-Control-Max-Age](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age)  |  `MaxAge`  |  `5` (預設)、`300`  | 

當您使用 Lambda 主控台或 設定函數 URL 的 CORS 時 AWS CLI，Lambda 會自動透過函數 URL 將 CORS 標頭新增至所有回應。或者，您也可以手動將 CORS 標頭新增至函數回應中。如果有衝突的標頭，預期的行為取決於請求的類型：
+ 對於 OPTIONS 請求等預檢請求，函數 URL 上設定的 CORS 標頭優先。Lambda 只會在回應中傳回這些 CORS 標頭。
+ 對於 GET 或 POST 請求等非預檢請求，Lambda 會傳回函數 URL 上設定的 CORS 標頭，以及函數傳回的 CORS 標頭。這可能會導致回應中出現重複的 CORS 標頭。您可能會看到類似如下的錯誤：`The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed`。

一般而言，我們建議在函數 URL 上設定所有 CORS 設定，而不是在函數回應中手動傳送 CORS 標頭。

## 調節函數 URL
<a name="urls-throttling"></a>

調節作業會限制函數處理請求的速度。這在許多情況下都相當實用，例如防止函數多載下游資源，或處理突然激增的請求數。

您可以設定預留並行，調節 Lambda 函數透過函數 URL 處理請求的速度。預留並行可限制函數的並行呼叫次數上限。函數的每秒請求率 (RPS) 上限相當於所設定預留並行數的 10 倍。例如，如果您將函數的預留並行值設為 100，則 RPS 最高為 1,000。

每當函數並行數量超過預留的並行數，函數 URL 就會傳回 HTTP `429` 狀態碼。如果函數收到的請求超過所設定預留並行數 10 倍的 RPS 最大值，您也會收到 HTTP `429` 錯誤。如需預留並行的詳細資訊，請參閱「[設定函數的預留並行](configuration-concurrency.md)」。

## 停用函數 URL
<a name="urls-deactivating"></a>

在緊急情況下，您可能會希望拒絕傳入函數 URL 的所有流量。若要停用函數 URL，請將預留並行設為零。這樣就能調節函數 URL 收到的所有請求，進而使 URL 傳回 HTTP `429` 狀態回應。如要重新啟動函數 URL，請刪除預留並行的組態，或將組態設為大於零的數量。

## 刪除函數 URL
<a name="w2aac39c81c53"></a>

當您刪除函數 URL，您就無法復原。建立新函數 URL 會產生不同的 URL 地址。

**注意**  
如果您刪除具有驗證類型 `NONE` 的函數 URL，Lambda 不會自動刪除關聯的資源型政策。如果您想要刪除此政策，則必須手動執行。

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇函數的名稱。

1. 選擇 **Configuration** (組態) 標籤，然後選擇 **Function URL** (函數 URL)。

1. 選擇 **刪除**。

1. 將 *delete* 一詞輸入欄位以確認刪除。

1. 選擇 **刪除**。

**注意**  
當您刪除具有函數 URL 的函數時，Lambda 會非同步刪除相應的函數 URL。如果您立即在相同帳戶中建立具有相同名稱的新函數，則原來的函數 URL 可能會映射到新的函數，而不會被刪除。

# 控制對 Lambda 函數 URL 的存取
<a name="urls-auth"></a>

**注意**  
自 2025 年 10 月起，新的函數 URL 將同時需要 `lambda:InvokeFunctionUrl` 和 `lambda:InvokeFunction` 許可。

您可以透過 [AuthType](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunctionUrlConfig.html#lambda-CreateFunctionUrlConfig-request-AuthType) 參數及連接至特定函數的[資源型政策](access-control-resource-based.md)，控制 Lambda 函數 URL 的存取權。這兩個元件的組態能決定誰可以對函數 URL 呼叫或執行其他管理動作。

`AuthType` 參數決定 Lambda 如何對函數 URL 的請求執行身分驗證或授權。設定函數 URL 時，您必須指定以下任一 `AuthType` 選項：
+ `AWS_IAM` – Lambda 使用 AWS Identity and Access Management (IAM) 根據 IAM 主體的身分政策和函數的資源型政策來驗證和授權請求。如果您希望僅允許已進行身分驗證的使用者和角色透過函數 URL 來調用函數，請選擇此選項。
+ `NONE` – Lambda 不會在呼叫函數前執行任何身分驗證。然而，函數的資源型政策永遠有效，而且您必須授予公有存取權，您的函數 URL 才能接收請求。選擇此選項，即可允許使用者公開存取函數 URL，而且不必完成身分驗證。

如需安全性的其他洞見，您可以使用 AWS Identity and Access Management Access Analyzer 來取得對函數 URL 的外部存取的完整分析。IAM Access Analyzer 也能監控您 Lambda 函數新增或更新的許可，以協助您識別授予公有和跨帳戶存取權的許可。您可以免費使用 IAM Access Analyzer。若要開始使用 IAM Access Analyzer，請參閱[使用 AWS IAM Access Analyzer](https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html)。

本頁提供了針對兩種身分驗證類型的資源型政策範例，也說明了如何使用 [AddPermission](https://docs.aws.amazon.com/lambda/latest/api/API_AddPermission.html) API 操作或 Lambda 主控台來建立這些政策。如需有關設定許可後如何調用函數 URL 的資訊，請參閱[呼叫 Lambda 函數 URL](urls-invocation.md)。

**Topics**
+ [

## 使用 `AWS_IAM` 驗證類型
](#urls-auth-iam)
+ [

## 使用 `NONE` 驗證類型
](#urls-auth-none)
+ [

## 控管和存取權控制
](#urls-governance)

## 使用 `AWS_IAM` 驗證類型
<a name="urls-auth-iam"></a>

如果您選擇採用 `AWS_IAM` 身分驗證類型，則使用者必須擁有 `lambda:InvokeFunctionUrl` 和 `lambda:InvokeFunction` 許可才能調用 Lambda 函數 URL。視提出調用請求的使用者而定，您可能需要透過[資源型政策](access-control-resource-based.md)才能授予此許可。

如果提出請求的委託人與函數 URL AWS 帳戶 位於相同位置，則委託人必須在其[身分型政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_identity-vs-resource.html)中****具有 `lambda:InvokeFunctionUrl`和 `lambda:InvokeFunction` 許可，**或在**函數的資源型政策中授予許可。換言之，若使用者已經透過資源型政策取得 `lambda:InvokeFunctionUrl` 和 `lambda:InvokeFunction` 許可，即可自行決定是否使用身分型政策。政策評估需遵循 [Policy evaluation logic](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html) 中概述的規則。

如果提出請求的主體位於不同帳戶，則主體必須**同時**透過身分型政策取得 `lambda:InvokeFunctionUrl` 和 `lambda:InvokeFunction` 許可，**並且**針對其嘗試調用的函式，透過資源型政策取得許可。政策評估需遵循 [Determining whether a cross-account request is allowed](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic-cross-account.html#policy-eval-cross-account) 中概述的規則。

下列資源型政策允許 中`example` AWS 帳戶 `444455556666`的角色叫用與函數 相關聯的函數 URL`my-function`。[lambda：InvokedViaFunctionUrl](https://docs.aws.amazon.com/lambda/latest/api/API_AddPermission.html#lambda-AddPermission-request-InvokedViaFunctionUrl) 內容索引鍵會將 `lambda:InvokeFunction` 動作限制為函數 URL 呼叫。這意味著主體必須使用函數 URL 來調用函數。如未包含 `lambda:InvokedViaFunctionUrl`，則主體除了函數 URL 外，還可以透過其他調用方法來調用函數。

**Example – 跨帳戶資源型政策**    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::444455556666:role/example"
      },
      "Action": "lambda:InvokeFunctionUrl",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
      "Condition": {
        "StringEquals": {
          "lambda:FunctionUrlAuthType": "AWS_IAM"
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::444455556666:role/example"
      },
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
      "Condition": {
        "Bool": {
          "lambda:InvokedViaFunctionUrl": "true"
        }
      }
    }
  ]
}
```

您可以依照下列步驟，透過主控台建立此資源型政策：

**將 URL 呼叫許可授予其他帳戶 (主控台)**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇您要授予 URL 呼叫許可的函數名稱。

1. 依序選擇 **Configuration** (組態) 索引標籤和 **Permissions** (許可)。

1. 在 **Resource-based policy** (資源型政策) 底下，選擇 **Add permissions** (新增許可)。

1. 選擇 **Function URL** (函數 URL)。

1. 針對 **Auth type** (驗證類型) 選擇 **AW\$1IAM**。

1. 輸入政策陳述式的**陳述式 ID**。

1. 依據要向其授予許可的使用者或角色，在**主體**中輸入其帳戶 ID 或 Amazon Resource Name (ARN)。例如：**444455556666**。

1. 選擇**儲存**。

或者，您可以使用下列 [add-permission](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/add-permission.html) AWS Command Line Interface (AWS CLI) 命令建立此政策。使用 時 AWS CLI，您必須分別新增 `lambda:InvokeFunctionUrl`和 `lambda:InvokeFunction`陳述式。例如：

```
aws lambda add-permission --function-name my-function \
  --statement-id UrlPolicyInvokeURL \
  --action lambda:InvokeFunctionUrl \
  --principal 444455556666 \
  --function-url-auth-type AWS_IAM
```

```
aws lambda add-permission --function-name my-function \
  --statement-id UrlPolicyInvokeFunction \
  --action lambda:InvokeFunction \
  --principal 444455556666 \
  --invoked-via-function-url
```

## 使用 `NONE` 驗證類型
<a name="urls-auth-none"></a>

**重要**  
當函數 URL 身分驗證類型為 `NONE`，並且透過[資源型政策](access-control-resource-based.md)授予公有存取權時，任何未經身分驗證的使用者只要取得函數 URL，即可調用對應函數。

在部分情況下，您可能需要將函數 URL 設定為公開存取。例如，您可能希望為直接透過 Web 瀏覽器提出的請求提供服務。如要允許使用者公開存取您的函數 URL，請選擇 `NONE` 驗證類型。

如果您選擇 `NONE` 驗證類型，Lambda 就不會使用 IAM 對存取函數 URL 的請求執行身分驗證。但是，函式必須具有允許 `lambda:InvokeFunctionUrl` 和 `lambda:InvokeFunction` 的資源型政策。當您`NONE`使用主控台或 AWS Serverless Application Model (AWS SAM) 建立具有身分驗證類型的函數 URL 時，Lambda 會自動為您建立以資源為基礎的政策。如果您直接使用 AWS CloudFormation AWS CLI或 Lambda API，則必須[自行新增政策](#policy-cli)。

建議在使用 `NONE` 身分驗證類型時，在資源型政策中包含 [lambda:InvokedViaFunctionUrl](https://docs.aws.amazon.com/lambda/latest/api/API_AddPermission.html#lambda-AddPermission-request-InvokedViaFunctionUrl) 內容索引鍵。此內容索引鍵可確保函數只能透過函數 URL 調用，而不能透過其他調用方法調用。

請注意有關此政策的下列資訊：
+ 所有實體都可以呼叫 `lambda:InvokeFunctionUrl` 和 `lambda:InvokeFunction`。這意味著任何擁有函數 URL 的使用者都可以調用函數。
+ `lambda:FunctionUrlAuthType` 條件索引鍵值為 `NONE`。這意味著，唯有當函數 URL 的身分驗證類型也是 `NONE` 時，此政策陳述式才會允許您存取函數 URL。
+ `lambda:InvokedViaFunctionUrl` 條件可確保函數只能透過函數 URL 調用，而不能透過其他調用方法調用。

**Example – NONE 身分驗證類型的預設資源型政策**    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "FunctionURLAllowPublicAccess",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "lambda:InvokeFunctionUrl",
      "Resource": "arn:aws:lambda:us-east-2:123456789012:function:my-function",
      "Condition": {
        "StringEquals": {
          "lambda:FunctionUrlAuthType": "NONE"
        }
      }
    },
    {
      "Sid": "FunctionURLInvokeAllowPublicAccess",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:us-east-2:123456789012:function:my-function",
      "Condition": {
        "Bool": {
          "lambda:InvokedViaFunctionUrl": "true"
        }
      }
    }
  ]
}
```

**使用 建立資源型政策 AWS CLI**  
除非您使用 主控台或 AWS SAM 建立身分驗證類型為 的函數 URL`NONE`，否則您必須自行新增資源型政策。使用下列命令為 `lambda:InvokeFunctionUrl` 和 `lambda:InvokeFunction` 許可建立陳述式。每個陳述式都必須在個別命令中進行新增。

```
aws lambda add-permission \
  --function-name UrlTestFunction \
  --statement-id UrlPolicyInvokeURL \
  --action lambda:InvokeFunctionUrl \
  --principal * \
  --function-url-auth-type NONE
```

```
aws lambda add-permission \
  --function-name UrlTestFunction \
  --statement-id UrlPolicyInvokeFunction \
  --action lambda:InvokeFunction \
  --principal * \
  --invoked-via-function-url
```

**注意**  
如果您刪除具有驗證類型 `NONE` 的函數 URL，Lambda 不會自動刪除關聯的資源型政策。如果您想要刪除此政策，則必須手動執行。

如果函數資源型政策並未授予 `lambda:invokeFunctionUrl` 和 `lambda:InvokeFunction` 許可，則當使用者嘗試調用函數 URL 時，將收到 403 Forbidden 錯誤代碼。即使函數 URL 使用 `NONE` 身分驗證類型，也會發生這種情況。

## 控管和存取權控制
<a name="urls-governance"></a>

除了函數 URL 呼叫許可之外，您也可以控制函數 URL 設定動作的存取權。Lambda 支援以下適用於函數 URL 的 IAM 政策動作：
+ `lambda:InvokeFunctionUrl` – 使用函數 URL 呼叫 Lambda 函數。
+ `lambda:CreateFunctionUrlConfig` – 建立函數 URL 並設定其 `AuthType`。
+ `lambda:UpdateFunctionUrlConfig` – 更新函數 URL 組態及其 `AuthType`。
+ `lambda:GetFunctionUrlConfig` – 檢視函數 URL 的詳細資訊。
+ `lambda:ListFunctionUrlConfigs` – 列出函數 URL 組態。
+ `lambda:DeleteFunctionUrlConfig` – 刪除函數 URL。

若要允許或拒絕其他 AWS 實體的函數 URL 存取，請在 IAM 政策中包含這些動作。例如，下列政策授予 `example`角色 AWS 帳戶 更新**my-function**帳戶 中函數的函數 URL 的`444455556666`許可`123456789012`。

**Example 跨帳戶函數 URL 政策**    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": { 
                "AWS": "arn:aws:iam::444455556666:role/example"
            },
            "Action": "lambda:UpdateFunctionUrlConfig",
            "Resource": "arn:aws:lambda:us-east-2:123456789012:function:my-function"
        }
    ]
}
```

### 條件索引鍵
<a name="urls-condition-keys"></a>

如要精細控制函數 URL 的存取權，請使用條件內容索引鍵。Lambda 為函數 URL 支援下列內容索引鍵：
+ `lambda:FunctionUrlAuthType`：定義描述函數 URL 所用身分驗證類型的列舉值。此值可以是 `AWS_IAM` 或 `NONE`。
+ `lambda:InvokedViaFunctionUrl`：將 `lambda:InvokeFunction` 動作限制為透過函數 URL 進行的呼叫。這可確保該函數只能使用函數 URL 調用，而不能透過其他調用方法調用。如需使用 `lambda:InvokedViaFunctionUrl` 內容索引鍵的資源型政策範例，請參閱[使用 `AWS_IAM` 驗證類型](#urls-auth-iam)與[使用 `NONE` 驗證類型](#urls-auth-none)中的範例。

您可以在與函式相關聯的政策中使用這些內容索引鍵。例如，您可能希望限制哪些人可以變更函數 URL 的組態。若要針對 URL 驗證類型為 `NONE` 的所有函數拒絕所有 `UpdateFunctionUrlConfig` 請求，您可以定義以下政策：

**Example 明確拒絕請求的函數 URL 政策**    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action":[
                "lambda:UpdateFunctionUrlConfig"
            ],
            "Resource": "arn:aws:lambda:us-east-1:123456789012:function:*",
            "Condition": {
                "StringEquals": {
                    "lambda:FunctionUrlAuthType": "NONE"
                }
            }
        }
    ]
}
```

若要授予 `example`角色 AWS 帳戶 `444455556666`許可，以對 URL 驗證類型為 的函數進行 `CreateFunctionUrlConfig`和 `UpdateFunctionUrlConfig`請求`AWS_IAM`，您可以定義下列政策：

**Example 明確允許請求的函數 URL 政策**    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": { 
                "AWS": "arn:aws:iam::444455556666:role/example"
            },
            "Action":[
                "lambda:CreateFunctionUrlConfig",
                "lambda:UpdateFunctionUrlConfig"
            ],
            "Resource": "arn:aws:lambda:us-east-1:123456789012:function:*",
            "Condition": {
                "StringEquals": {
                    "lambda:FunctionUrlAuthType": "AWS_IAM"
                }
            }
        }
    ]
}
```

您也可以在服[務控制政策](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html)(SCP) 中使用此條件索引鍵。在 AWS Organizations中使用 SCP 管理整個組織的許可。例如，若要拒絕使用者建立或更新使用 `AWS_IAM` 以外驗證類型的函數 URL，請使用以下服務控制政策：

**Example 明確拒絕請求的函數 URL SCP**    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Deny",
            "Action":[
                "lambda:CreateFunctionUrlConfig",
                "lambda:UpdateFunctionUrlConfig"
            ],
            "Resource": "arn:aws:lambda:*:123456789012:function:*",
            "Condition": {
                "StringNotEquals": {
                    "lambda:FunctionUrlAuthType": "AWS_IAM"
                }
            }
        }
    ]
}
```

# 呼叫 Lambda 函數 URL
<a name="urls-invocation"></a>

函數 URL 是 Lambda 函數專用的 HTTP(S) 端點。您可以透過 Lambda 主控台或 Lambda API 建立及設定函數 URL。

**提示**  
Lambda 提供兩種透過 HTTP 端點調用函式的方式：函式 URL 與 Amazon API Gateway。如果不確定哪種方法最適合自己的使用案例，請參閱[選取一種使用 HTTP 請求調用 Lambda 函數的方法](furls-http-invoke-decision.md)。

當您建立函數 URL 時，Lambda 會自動為您產生不重複的 URL 端點。函數 URL 一旦建立，其 URL 端點便永遠不會變更。函數 URL 端點的格式如下：

```
https://<url-id>.lambda-url.<region>.on.aws
```

**注意**  
下列 AWS 區域不支援函式 URL：亞太區域 (海德拉巴) (`ap-south-2`)、亞太區域 (墨爾本) (`ap-southeast-4`)、亞太區域 (馬來西亞) (`ap-southeast-5`)、亞太區域 (紐西蘭) (`ap-southeast-6`)、亞太區域 (泰國) (`ap-southeast-7`)、亞太區域 (台北) (`ap-east-2`)、加拿大西部 (卡加利)(`ca-west-1`)、歐洲 (西班牙) (`eu-south-2`)、歐洲 (蘇黎世) (`eu-central-2`)、以色列 (特拉維夫) (`il-central-1`) 以及中東 (阿拉伯聯合大公國) (`me-central-1`)。

函數 URL 可支援雙堆疊，能同時支援 IPv4 和 IPv6。設定函數 URL 後，您可以利用 Web 瀏覽器、curl、Postman 或任何 HTTP 用戶端，透過 HTTP(S) 端點呼叫函數。若要調用函式 URL，您必須擁有 `lambda:InvokeFunctionUrl` 和 `lambda:InvokeFunction` 許可。如需更多詳細資訊，請參閱 [存取控制](urls-auth.md)。

**Topics**
+ [

## 函數 URL 呼叫基礎知識
](#urls-invocation-basics)
+ [

## 請求和回應承載
](#urls-payloads)

## 函數 URL 呼叫基礎知識
<a name="urls-invocation-basics"></a>

如果您的函數 URL 使用 `AWS_IAM` 驗證類型，您必須使用 [AWS Signature 第 4 版 (SigV4)](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) 簽署各個 HTTP 請求。[Postman](https://quickstarts.postman.com/guide/aws/index.html?index=..%2F..index#2) 等工具提供使用 SigV4 簽署請求的內建功能。

如果您不使用工具簽署函數 URL 的 HTTP 請求，則必須使用 SigV4 手動簽署各個請求。您的函數 URL 收到請求時，Lambda 也會計算 SigV4 簽章。唯有簽章相符，Lambda 才會處理請求。如需使用 SigV4 手動簽署請求的相關說明，請參閱《Amazon Web Services 一般參考 指南》**中的[使用 Signature 第 4 版簽署 AWS 請求](https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html)。

如果您的函數 URL 使用 `NONE` 驗證類型，您不必使用 SigV4 簽署請求。您可以使用 Web 瀏覽器、curl、Postman 或任何 HTTP 用戶端來呼叫您的函數。

如要測試函數的簡易 `GET` 請求，請使用 Web 瀏覽器。例如，如果函數 URL 為 `https://abcdefg.lambda-url.us-east-1.on.aws`，而且接受字串參數 `message`，則請求 URL 可能如下所示：

```
https://abcdefg.lambda-url.us-east-1.on.aws/?message=HelloWorld
```

如要測試其他 HTTP 請求 (例如 `POST` 請求)，您可以使用 curl 等工具。例如，如果您希望在函數 URL 的 `POST` 請求中納入某些 JSON 資料，您可以使用下列 curl 命令：

```
curl -v 'https://abcdefg.lambda-url.us-east-1.on.aws/?message=HelloWorld' \
-H 'content-type: application/json' \
-d '{ "example": "test" }'
```

## 請求和回應承載
<a name="urls-payloads"></a>

用戶端呼叫您的函數 URL 時，Lambda 會先將請求映射至事件物件，再將請求傳遞給函數。接著，函數的回應會映射至 Lambda 透過函數 URL 回傳給用戶端的 HTTP 回應。

請求和回應事件格式會採取與 [Amazon API Gateway 承載格式 2.0 版](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html#http-api-develop-integrations-lambda.proxy-format)一樣的結構描述。

### 請求承載格式
<a name="urls-request-payload"></a>

請求承載的結構如下：

```
{
  "version": "2.0",
  "routeKey": "$default",
  "rawPath": "/my/path",
  "rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
  "cookies": [
    "cookie1",
    "cookie2"
  ],
  "headers": {
    "header1": "value1",
    "header2": "value1,value2"
  },
  "queryStringParameters": {
    "parameter1": "value1,value2",
    "parameter2": "value"
  },
  "requestContext": {
    "accountId": "123456789012",
    "apiId": "<urlid>",
    "authentication": null,
    "authorizer": {
        "iam": {
                "accessKey": "AKIA...",
                "accountId": "111122223333",
                "callerId": "AIDA...",
                "cognitoIdentity": null,
                "principalOrgId": null,
                "userArn": "arn:aws:iam::111122223333:user/example-user",
                "userId": "AIDA..."
        }
    },
    "domainName": "<url-id>.lambda-url.us-west-2.on.aws",
    "domainPrefix": "<url-id>",
    "http": {
      "method": "POST",
      "path": "/my/path",
      "protocol": "HTTP/1.1",
      "sourceIp": "123.123.123.123",
      "userAgent": "agent"
    },
    "requestId": "id",
    "routeKey": "$default",
    "stage": "$default",
    "time": "12/Mar/2020:19:03:58 +0000",
    "timeEpoch": 1583348638390
  },
  "body": "Hello from client!",
  "pathParameters": null,
  "isBase64Encoded": false,
  "stageVariables": null
}
```


| 參數 | 描述 | 範例 | 
| --- | --- | --- | 
|  `version`  |  此事件的承載格式版本。Lambda 函數 URL 目前支援[承載格式 2.0 版](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html#http-api-develop-integrations-lambda.proxy-format)。  |  `2.0`  | 
|  `routeKey`  |  函數 URL 不使用此參數。Lambda 將此設為 `$default` 作為預留位置使用。  |  `$default`  | 
|  `rawPath`  |  請求路徑。例如，如果請求 URL 為 `https://{url-id}.lambda-url.{region}.on.aws/example/test/demo`，則原始路徑值為 `/example/test/demo`。  |  `/example/test/demo`  | 
|  `rawQueryString`  |  內含請求查詢字串參數的原始字串。支援的字元包含 `a-z`、`A-Z`、`0-9`、`.`、`_`、`-`、`%`、`&`、`=`，以及 `+`。  |  `"?parameter1=value1&parameter2=value2"`  | 
|  `cookies`  |  內含隨請求一併傳送之所有 Cookie 的陣列。  |  `["Cookie_1=Value_1", "Cookie_2=Value_2"]`  | 
|  `headers`  |  以鍵值對形式呈現的請求標頭清單。  |  `{"header1": "value1", "header2": "value2"}`  | 
|  `queryStringParameters`  |  請求的查詢參數。例如，如果請求 URL 為 `https://{url-id}.lambda-url.{region}.on.aws/example?name=Jane`，則 `queryStringParameters` 值為具備索引鍵 `name` 和值 `Jane` 的 JSON 物件。  |  `{"name": "Jane"}`  | 
|  `requestContext`  |  內含請求其他資訊的物件，例如 `requestId`、請求的時間，以及呼叫者的身分 (如果透過 AWS Identity and Access Management (IAM) 取得授權的話)。  |   | 
|  `requestContext.accountId`  |  函數擁有者的 AWS 帳戶 ID。  |  `"123456789012"`  | 
|  `requestContext.apiId`  |  函數 URL 的 ID。  |  `"33anwqw8fj"`  | 
|  `requestContext.authentication`  |  函數 URL 不使用此參數。Lambda 將此設為 `null`。  |  `null`  | 
|  `requestContext.authorizer`  |  內含呼叫者身分相關資訊的物件 (如果函數 URL 使用 `AWS_IAM` 驗證類型的話)，否則 Lambda 會將此設為 `null`。  |   | 
|  `requestContext.authorizer.iam.accessKey`  |  呼叫者身分的存取金鑰。  |  `"AKIAIOSFODNN7EXAMPLE"`  | 
|  `requestContext.authorizer.iam.accountId`  |  呼叫者身分的 AWS 帳戶 ID。  |  `"111122223333"`  | 
|  `requestContext.authorizer.iam.callerId`  |  呼叫者的 ID (使用者 ID)。  |  `"AIDACKCEVSQ6C2EXAMPLE"`  | 
|  `requestContext.authorizer.iam.cognitoIdentity`  |  函數 URL 不使用此參數。Lambda 將此設為 `null`，或將此從 JSON 排除。  |  `null`  | 
|  `requestContext.authorizer.iam.principalOrgId`  |  與呼叫者身分相關聯的委託人組織 ID。  |  `"AIDACKCEVSQORGEXAMPLE"`  | 
|  `requestContext.authorizer.iam.userArn`  |  呼叫者身分的使用者 Amazon Resource Name (ARN)。  |  `"arn:aws:iam::111122223333:user/example-user"`  | 
|  `requestContext.authorizer.iam.userId`  |  呼叫者身分的使用者 ID。  |  `"AIDACOSFODNN7EXAMPLE2"`  | 
|  `requestContext.domainName`  |  函數 URL 的網域名稱。  |  `"<url-id>.lambda-url.us-west-2.on.aws"`  | 
|  `requestContext.domainPrefix`  |  函數 URL 的網域前綴。  |  `"<url-id>"`  | 
|  `requestContext.http`  |  內含 HTTP 請求詳細資訊的物件。  |   | 
|  `requestContext.http.method`  |  此請求所採用的 HTTP 方法。有效值包括 `GET`、`POST`、`PUT`、`HEAD`、`OPTIONS`、`PATCH` 和 `DELETE`。  |  `GET`  | 
|  `requestContext.http.path`  |  請求路徑。例如，如果請求 URL 為 `https://{url-id}.lambda-url.{region}.on.aws/example/test/demo`，則路徑值為 `/example/test/demo`。  |  `/example/test/demo`  | 
|  `requestContext.http.protocol`  |  請求的通訊協定。  |  `HTTP/1.1`  | 
|  `requestContext.http.sourceIp`  |  提出請求之即時 TCP 連線的來源 IP 地址。  |  `123.123.123.123`  | 
|  `requestContext.http.userAgent`  |  使用者代理程式請求標頭的值。  |  `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Gecko/20100101 Firefox/42.0`  | 
|  `requestContext.requestId`  |  呼叫請求的 ID。您可以使用此 ID 追蹤與函數相關的呼叫日誌。  |  `e1506fd5-9e7b-434f-bd42-4f8fa224b599`  | 
|  `requestContext.routeKey`  |  函數 URL 不使用此參數。Lambda 將此設為 `$default` 作為預留位置使用。  |  `$default`  | 
|  `requestContext.stage`  |  函數 URL 不使用此參數。Lambda 將此設為 `$default` 作為預留位置使用。  |  `$default`  | 
|  `requestContext.time`  |  請求的時間戳記。  |  `"07/Sep/2021:22:50:22 +0000"`  | 
|  `requestContext.timeEpoch`  |  Unix epoch 時間格式的請求時間戳記。  |  `"1631055022677"`  | 
|  `body`  |  請求的本文。如果請求的內容屬於二進位類型，則本文會採用 base64 編碼。  |  `{"key1": "value1", "key2": "value2"}`  | 
|  `pathParameters`  |  函數 URL 不使用此參數。Lambda 將此設為 `null`，或將此從 JSON 排除。  |  `null`  | 
|  `isBase64Encoded`  |  如果本文為二進位承載並採用 base64 編碼，此值為 `TRUE`，否則為 `FALSE`。  |  `FALSE`  | 
|  `stageVariables`  |  函數 URL 不使用此參數。Lambda 將此設為 `null`，或將此從 JSON 排除。  |  `null`  | 

### 回應承載格式
<a name="urls-response-payload"></a>

函數傳回回應時，Lambda 會剖析回應內容，並將其轉換為 HTTP 回應。函數回應承載的格式如下：

```
{
   "statusCode": 201,
    "headers": {
        "Content-Type": "application/json",
        "My-Custom-Header": "Custom Value"
    },
    "body": "{ \"message\": \"Hello, world!\" }",
    "cookies": [
        "Cookie_1=Value1; Expires=21 Oct 2021 07:48 GMT",
        "Cookie_2=Value2; Max-Age=78000"
    ],
    "isBase64Encoded": false
}
```

Lambda 會為您推斷回應格式。如果您的函數傳回有效的 JSON，但未傳回 `statusCode`，則 Lambda 會採取下列假設：
+ `statusCode`is(`200` )
**注意**  
有效 `statusCode` 的範圍為 100 至 599。
+ `content-type`is(`application/json` )
+ `body` 是函數的回應。
+ `isBase64Encoded`is(`false` )

以下範例顯示 Lambda 函數輸出與回應承載之間的映射情形，以及回應承載與最終 HTTP 回應之間的映射情形。用戶端呼叫您的函數 URL 時，會看見 HTTP 回應。

**字串回應的輸出範例**


| Lambda 函數輸出 | 轉譯後的回應輸出 | HTTP 回應 (用戶端看見的內容) | 
| --- | --- | --- | 
|  <pre>"Hello, world!"</pre>  |  <pre>{<br />  "statusCode": 200,<br />  "body": "Hello, world!",<br />  "headers": {<br />    "content-type": "application/json"<br />  },<br />  "isBase64Encoded": false<br />}</pre>  |  <pre>HTTP/2 200<br />date: Wed, 08 Sep 2021 18:02:24 GMT<br />content-type: application/json<br />content-length: 15<br /><br />"Hello, world!"</pre>  | 

**JSON 回應的輸出範例**


| Lambda 函數輸出 | 轉譯後的回應輸出 | HTTP 回應 (用戶端看見的內容) | 
| --- | --- | --- | 
|  <pre>{<br />  "message": "Hello, world!"<br />}</pre>  |  <pre>{<br />  "statusCode": 200,<br />  "body": {<br />    "message": "Hello, world!"<br />  },<br />  "headers": {<br />    "content-type": "application/json"<br />  },<br />  "isBase64Encoded": false<br />}</pre>  |  <pre>HTTP/2 200<br />date: Wed, 08 Sep 2021 18:02:24 GMT<br />content-type: application/json<br />content-length: 34<br /><br />{<br />  "message": "Hello, world!"<br />}</pre>  | 

**自訂回應的輸出範例**


| Lambda 函數輸出 | 轉譯後的回應輸出 | HTTP 回應 (用戶端看見的內容) | 
| --- | --- | --- | 
|  <pre>{<br />   "statusCode": 201,<br />    "headers": {<br />        "Content-Type": "application/json",<br />        "My-Custom-Header": "Custom Value"<br />    },<br />    "body": JSON.stringify({<br />        "message": "Hello, world!"<br />    }),<br />    "isBase64Encoded": false<br />}</pre>  |  <pre>{<br />   "statusCode": 201,<br />    "headers": {<br />        "Content-Type": "application/json",<br />        "My-Custom-Header": "Custom Value"<br />    },<br />    "body": JSON.stringify({<br />        "message": "Hello, world!"<br />    }),<br />    "isBase64Encoded": false<br />}</pre>  |  <pre>HTTP/2 201<br />date: Wed, 08 Sep 2021 18:02:24 GMT<br />content-type: application/json<br />content-length: 27<br />my-custom-header: Custom Value<br /><br />{<br />  "message": "Hello, world!"<br />}</pre>  | 

### Cookie
<a name="urls-cookies"></a>

如要從函數傳回 Cookie，請勿手動新增 `set-cookie` 標頭。您應將 Cookie 加入回應承載物件中。Lambda 會自動轉譯 Cookie，並以 `set-cookie` 標頭形式新增至 HTTP 回應，如下所示。


| Lambda 函數輸出 | HTTP 回應 (用戶端看見的內容) | 
| --- | --- | 
|  <pre>{<br />   "statusCode": 201,<br />    "headers": {<br />        "Content-Type": "application/json",<br />        "My-Custom-Header": "Custom Value"<br />    },<br />    "body": JSON.stringify({<br />        "message": "Hello, world!"<br />    }),<br />    "cookies": [<br />        "Cookie_1=Value1; Expires=21 Oct 2021 07:48 GMT",<br />        "Cookie_2=Value2; Max-Age=78000"<br />    ],<br />    "isBase64Encoded": false<br />}</pre>  |  <pre>HTTP/2 201<br />date: Wed, 08 Sep 2021 18:02:24 GMT<br />content-type: application/json<br />content-length: 27<br />my-custom-header: Custom Value<br />set-cookie: Cookie_1=Value2; Expires=21 Oct 2021 07:48 GMT<br />set-cookie: Cookie_2=Value2; Max-Age=78000<br /><br />{<br />  "message": "Hello, world!"<br />}</pre>  | 

# 監控 Lambda 函數 URL
<a name="urls-monitoring"></a>

您可以使用 AWS CloudTrail 和 Amazon CloudWatch 監控函數 URL。

**Topics**
+ [

## 使用 CloudTrail 監控函數 URL
](#urls-cloudtrail)
+ [

## 函數 URL 的 CloudWatch 指標
](#urls-cloudwatch)

## 使用 CloudTrail 監控函數 URL
<a name="urls-cloudtrail"></a>

針對函數 URL，Lambda 能將下列 API 操作記錄為 CloudTrail 日誌檔案事件：
+ [CreateFunctionUrlConfig](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunctionUrlConfig.html)
+ [UpdateFunctionUrlConfig](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionUrlConfig.html)
+ [DeleteFunctionUrlConfig](https://docs.aws.amazon.com/lambda/latest/api/API_DeleteFunctionUrlConfig.html)
+ [GetFunctionUrlConfig](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionUrlConfig.html)
+ [ListFunctionUrlConfigs](https://docs.aws.amazon.com/lambda/latest/api/API_ListFunctionUrlConfigs.html)

每個日誌項目都包含呼叫者身分、提出請求的時間，以及其他詳細資訊等相關資訊。您可以檢視 CloudTrail **事件歷史記錄**，查看過去 90 天內的所有事件。如要保留 90 天前的記錄，您可以建立線索。

預設情況下，CloudTrail 不會記錄 `InvokeFunctionUrl` 請求，系統會將這些請求視為資料事件。不過，您可以在 CloudTrail 中開啟資料事件記錄功能。如需詳細資訊，請參閱《AWS CloudTrail使用者指南》**中的[記錄資料事件](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-data-events-with-cloudtrail.html)。

## 函數 URL 的 CloudWatch 指標
<a name="urls-cloudwatch"></a>

Lambda 會將函數 URL 請求的彙總指標傳送到 CloudWatch。透過這些指標，您可以在 CloudWatch 主控台中監控函數 URL、建置儀錶板及設定警示。

函數 URL 支援以下呼叫指標。建議您搭配 `Sum` 統計數字一併檢視這些指標。
+ `UrlRequestCount` – 對此函數提出的請求數量。
+ `Url4xxCount` – 傳回 4XX HTTP 狀態碼的請求數量。收到 4XX 系列代碼表示用戶端發生錯誤，例如請求錯誤。
+ `Url5xxCount` – 傳回 5XX HTTP 狀態碼的請求數量。收到 5XX 系列代碼表示伺服器端發生錯誤，例如函數錯誤和逾時。

函數 URL 也支援以下效能指標。建議您搭配 `Average` 或 `Max` 統計數字一併檢視這些指標。
+ `UrlRequestLatency` – 函數 URL 從收到請求到傳回回應所經過的時間。

這些呼叫和效能指標均支援以下維度：
+ `FunctionName` – 針對指派給函數`$LATEST`未發佈版本或任何函數別名的函數 URL，查看其彙總指標，例如 `hello-world-function`。
+ `Resource` – 檢視特定函數 URL 的指標。您可使用函數名稱，並搭配函數未發佈的`$LATEST`版本或任一函數別名來加以定義，例如 `hello-world-function:$LATEST`。
+ `ExecutedVersion` – 根據所執行的版本檢視特定函數 URL 的指標。此維度的主要功能是追蹤指派給`$LATEST`未發佈版本的函數 URL。

# 選取一種使用 HTTP 請求調用 Lambda 函數的方法
<a name="furls-http-invoke-decision"></a>

Lambda 的許多常見使用案例涉及使用 HTTP 請求調用您的函數。例如，您可能希望 Web 應用程式透過瀏覽器請求調用您的函式。Lambda 函式也可用於建立完整的 REST API、處理來自行動應用程式的使用者互動、透過 HTTP 呼叫處理來自外部服務的資料，或建立自訂 Webhook。

以下各節說明透過 HTTP 調用 Lambda 的選擇，並提供資訊以協助您針對特定使用案例做出正確決策。

## 選取 HTTP 調用方法時，您有哪些選擇？
<a name="w2aac39c81c73b9"></a>

Lambda 提供兩種主要方法來使用 HTTP 請求調用函數 - [函數 URL](urls-configuration.md) 和 [API Gateway](services-apigateway.md)。這兩種選項的主要差異如下所示：
+ **Lambda 函數 URL** 可為 Lambda 函數提供簡單、直接的 HTTP 端點。已針對簡單性和成本效益對其進行最佳化，並提供透過 HTTP 公開 Lambda 函數的最快路徑。
+ **API Gateway** 是一種更進階的服務，用於建置功能完整的 API。API Gateway 已針對大規模建置和管理生產 API 進行最佳化，並提供完整的安全、監控和流量管理工具。

## 您已知道自己需求時的建議
<a name="w2aac39c81c73c11"></a>

如果您已經清楚自己的需求，以下是基本建議：

建議**[函數 URL](urls-configuration.md)** 用於簡單的應用程式或原型設計，其中您只需要基本的身分驗證方法和請求/回應處理，並想要將成本和複雜性降至最低。

**[API Gateway](services-apigateway.md)** 是大規模生產應用程式或需要更進階功能的情況的更佳選擇，例如 [OpenAPI Description](https://www.openapis.org/) 支援、身分驗證選項、自訂網域名稱或豐富的請求/回應處理，包括限流、快取和請求/回應轉換。

## 選擇調用 Lambda 函數的方法時應考慮的事項
<a name="w2aac39c81c73c13"></a>

在函數 URL 和 API Gateway 之間選取時，需要考慮下列因素：
+ 您的身分驗證需要，例如是否需要 OAuth 或 Amazon Cognito 來驗證使用者
+ 您的擴展需求以及您要實作之 API 的複雜性
+ 您是否需要進階功能，例如請求驗證和請求/回應格式化
+ 您的監控需求
+ 您的成本目標

透過了解這些因素，可以選擇最能平衡您的安全性、複雜性和成本需求的選項。

下列資訊摘要說明兩個選項之間的主要差異。

### 身分驗證
<a name="w2aac39c81c73c13c11b1"></a>
+ **函數 URLs**提供基本身分驗證選項。 AWS Identity and Access Management 可以將端點設定為公有 (無身分驗證) 或需要 IAM 身分驗證。透過 IAM 身分驗證，您可以使用標準 AWS 登入資料或 IAM 角色來控制存取。雖然設定簡單，但相較於其他驗證方法，此方法提供的選項有限。
+ **API Gateway** 可存取更全面的身分驗證選項。除了 IAM 身分驗證之外，也可以使用 [Lambda 授權工具](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html) (自訂身分驗證邏輯)、[Amazon Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html) 使用者集區和 OAuth2.0 流程。此彈性可讓您實作複雜的身分驗證機制，包括第三方身分驗證提供者、權杖型身分驗證和多重要素身分驗證。

### 請求/回應處理
<a name="w2aac39c81c73c13c11b3"></a>
+ **函數 URL** 提供基本的 HTTP 請求和回應處理。它們支援標準 HTTP 方法，並包含內建的跨來源資源共用 (CORS) 支援。雖然他們可以自然處理 JSON 承載和查詢參數，但它們不提供請求轉換或驗證功能。回應處理同樣簡單 – 用戶端接收來自 Lambda 函數的回應，就像 Lambda 傳回它一樣。
+ **API Gateway** 可提供複雜的請求和回應處理功能。您可以定義請求驗證器，使用映射範本轉換請求和回應，設定請求/回應標頭，以及實作回應快取。API Gateway 也支援二進位承載和自訂網域名稱，並且可以在回應到達用戶端之前對其進行修改。可以使用 JSON 結構描述來設定請求/回應驗證和轉換的模型。

### 擴展
<a name="w2aac39c81c73c13c11b5"></a>
+ **函數 URL** 會根據 Lambda 函數的並行限制直接擴展，並透過將函數擴展到其設定的並行限制上限來處理流量尖峰。達到該限制後，Lambda 會使用 HTTP 429 回應來回應其他請求。沒有內建佇列機制，因此處理擴展完全取決於 Lambda 函數的組態。根據預設，Lambda 函數每個 有 1，000 個並行執行的限制 AWS 區域。
+ 除了 Lambda 自己的擴展之外，**API Gateway** 還提供其他擴展功能。它包含內建的請求佇列和限流控制，可讓您更輕鬆地管理流量尖峰。根據預設，API Gateway 每秒最多可以處理 10,000 個請求，高載容量為每秒 5,000 個請求。它也提供在不同層級調節請求的工具 (API、階段或方法)，以保護後端。

### 監控
<a name="w2aac39c81c73c13c11b7"></a>
+ **函數 URL** 透過 Amazon CloudWatch 指標提供基本監控，包括請求計數、延遲和錯誤率。可以存取標準 Lambda 指標和日誌，它們會顯示傳入函數的原始請求。雖然這可提供基本的操作可見性，但指標主要著重於函數執行。
+ **API Gateway** 提供全面的監控功能，包括詳細的指標、記錄和追蹤選項。可以透過 CloudWatch 來監控 API 呼叫、延遲、錯誤率和快取命中率/遺失率。API Gateway 也會整合 與 AWS X-Ray 以進行分散式追蹤，並提供可自訂的記錄格式。

### Cost
<a name="w2aac39c81c73c13c11b9"></a>
+ **函數 URL** 遵循標準 Lambda 定價模型 – 您只需支付函數調用和運算時間的費用。URL 端點本身不收取額外費用。如果您不需要 API Gateway 的其他功能，這對於簡單的 API 或低流量應用程式而言是一個具成本效益的選擇。
+ **API Gateway** 提供[免費方案](https://aws.amazon.com/api-gateway/pricing/#Free_Tier)，其中包含針對 REST API 收到的一百萬個 API 呼叫，以及針對 HTTP API 收到的一百萬個 API 呼叫。之後，API Gateway 會針對 API 呼叫、資料傳輸和快取 (如果啟用) 收取費用。請參閱 API Gateway [定價頁面](https://aws.amazon.com/api-gateway/pricing/)，了解您自己的使用案例費用。

### 其他功能
<a name="w2aac39c81c73c13c11c11"></a>
+ **函數 URL** 旨在實現簡便性和直接 Lambda 整合。它們支援 HTTP 和 HTTPS 端點，提供內建 CORS 支援，並提供雙堆疊 (IPv4 和 IPv6) 端點。雖然它們缺乏進階功能，但它們在您需要快速、直接地透過 HTTP 公開 Lambda 函數時表現卓越。
+ **API Gateway** 包含許多其他功能，例如 API 版本控制、階段管理、用於用量計劃的 API 金鑰、透過 Swagger/OpenAPI 的 API 文件、WebSocket API、VPC 中的私有 API 以及 WAF 整合，以提供額外的安全性。它還支援 Canary 部署、用於測試的模擬整合，以及與 Lambda AWS 服務 以外的其他 整合。

## 選取調用 Lambda 函數的方法
<a name="w2aac39c81c73c15"></a>

現在您已了解在 Lambda 函數 URL 和 API Gateway 之間進行選擇的條件，以及它們之間的主要差異，您可以選擇最符合您需求的選項，並使用下列資源來協助您開始使用。

------
#### [ Function URLs ]

**使用下列資源開始使用函數 URL**
+ 遵循教學課程[建立具有函數 URL 的 Lambda 函數](urls-webhook-tutorial.md)
+ 在本指南的 [建立及管理 Lambda 函數 URL](urls-configuration.md) 章節中進一步了解 函數 URL
+ 透過執行以下操作，嘗試主控台內的引導式教學課程**建立簡單的 Web 應用程式**：

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇畫面右上角的圖示以開啟說明面板。  
![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/console_help_screenshot.png)

1. 選取**教學課程**。

1. 在**建立簡單的 Web 應用程式中**，選擇**開始教學課程**。

------
#### [ API Gateway ]

**使用下列資源開始使用 Lambda 和 API Gateway**
+ 依照教學課程[搭配使用 Lambda 與 API Gateway](services-apigateway-tutorial.md) 來建立與後端 Lambda 函數整合的 REST API。
+ 在 *Amazon API Gateway 開發人員指南*的下列章節中，進一步了解 API Gateway 提供的不同類型 API：
  + [API Gateway REST API](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-rest-api.html)
  + [API Gateway HTTP API](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api.html)
  + [API Gateway WebSocket API](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api.html)
+ 請嘗試 *Amazon API Gateway 開發人員指南*的[教學課程和研討會](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-tutorials.html)一節中的一個或多個範例。

------

# 教學課程：使用 Lambda 函式 URL 建立 Webhook 端點
<a name="urls-webhook-tutorial"></a>

在本教學課程中，您將建立 Lambda 函式 URL 來實作 Webhook 端點。Webhook 是一種輕量型的事件驅動型通訊機制，能透過 HTTP 自動在應用程式間傳輸資料。您可以使用 Webhook 來接收有關其他系統中發生事件的即時更新，例如當新客戶在網站上註冊、處理付款或上傳檔案時。

使用 Lambda 時，可以透過 Lambda 函式 URL 或 API Gateway 來實作 Webhook。對於不需要進階授權或請求驗證等功能的簡單 Webhook，函式 URL 是很好的選擇。

**提示**  
如果您不確定哪種解決方案最適合特定使用案例，請參閱[選取一種使用 HTTP 請求調用 Lambda 函數的方法](furls-http-invoke-decision.md)。

## 先決條件
<a name="urls-webhook-tutorial-prereqs"></a>

要完成本教學課程，必須在本機電腦上安裝 Python (3.8 版或更新版本) 或 Node.js (18 版或更新版本)。

為了使用 HTTP 請求測試端點，本教學課程使用了 [curl](https://curl.se/)。這是一個命令列工具，能透過多種網路通訊協定來傳輸資料。若尚未安裝此工具，請參閱 [curl 文件](https://curl.se/docs/install.html)了解安裝方法。

## 建立 Lambda 函式
<a name="urls-webhook-tutorial-function"></a>

首先建立當 HTTP 請求傳送至 Webhook 端點時執行的 Lambda 函式。在此範例中，傳送端應用程式會在付款提交時傳送更新，並在 HTTP 請求內文中指出付款是否成功。Lambda 函式會剖析請求，再依據付款狀態採取動作。在此範例中，程式碼僅會列印付款的訂單 ID，但在實際應用程式中，您可以將訂單新增至資料庫或傳送通知。

函式還實作了 Webhook 最常用的身分驗證方法，即雜湊訊息驗證碼 (HMAC)。使用此方法時，傳送端與接收端應用程式皆會共用一個秘密金鑰。傳送端應用程式使用雜湊演算法，利用此金鑰和訊息內容產生唯一簽章，並將該簽章作為 HTTP 標頭包含在 Webhook 請求中。然後，接收端應用程式會重複此步驟，使用秘密金鑰產生簽章，並將結果值與請求標頭中傳送的簽章進行比較。如果結果相符，請求會視為合法。

使用 Lambda 主控台並選擇 Python 或 Node.js 執行時期來建立函式。

------
#### [ Python ]

**建立 Lambda 函式**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 執行下列動作，建立基本的 'Hello world' 函式：

   1. 選擇 **Create function (建立函數)**。

   1. 選取**從頭開始撰寫**。

   1. 針對**函數名稱**，請輸入 **myLambdaWebhook**。

   1. 針對**執行期**，選取 **python3.14**。

   1. 選擇 **Create function (建立函數)**。

1. 在**程式碼來源**窗格中，複製並貼上以下項目來取代現有程式碼：

   ```
   import json
   import hmac
   import hashlib
   import os
   
   def lambda_handler(event, context):
       
       # Get the webhook secret from environment variables
       webhook_secret = os.environ['WEBHOOK_SECRET']
       
       # Verify the webhook signature
       if not verify_signature(event, webhook_secret):
           return {
               'statusCode': 401,
               'body': json.dumps({'error': 'Invalid signature'})
           }
       
       try:
           # Parse the webhook payload
           payload = json.loads(event['body'])
           
           # Handle different event types
           event_type = payload.get('type')
           
           if event_type == 'payment.success':
               # Handle successful payment
               order_id = payload.get('orderId')
               print(f"Processing successful payment for order {order_id}")
               
               # Add your business logic here
               # For example, update database, send notifications, etc.
               
           elif event_type == 'payment.failed':
               # Handle failed payment
               order_id = payload.get('orderId')
               print(f"Processing failed payment for order {order_id}")
               
               # Add your business logic here
               
           else:
               print(f"Received unhandled event type: {event_type}")
           
           # Return success response
           return {
               'statusCode': 200,
               'body': json.dumps({'received': True})
           }
           
       except json.JSONDecodeError:
           return {
               'statusCode': 400,
               'body': json.dumps({'error': 'Invalid JSON payload'})
           }
       except Exception as e:
           print(f"Error processing webhook: {e}")
           return {
               'statusCode': 500,
               'body': json.dumps({'error': 'Internal server error'})
           }
   
   def verify_signature(event, webhook_secret):
       """
       Verify the webhook signature using HMAC
       """
       try:
           # Get the signature from headers
           signature = event['headers'].get('x-webhook-signature')
   
           if not signature:
               print("Error: Missing webhook signature in headers")
               return False
           
           # Get the raw body (return an empty string if the body key doesn't exist)
           body = event.get('body', '')
           
           # Create HMAC using the secret key
           expected_signature = hmac.new(
               webhook_secret.encode('utf-8'),
               body.encode('utf-8'),
               hashlib.sha256
           ).hexdigest()
           
           # Compare the expected signature with the received signature to authenticate the message
           is_valid = hmac.compare_digest(signature, expected_signature)
           if not is_valid:
               print(f"Error: Invalid signature. Received: {signature}, Expected: {expected_signature}")
               return False
               
           return True
       except Exception as e:
           print(f"Error verifying signature: {e}")
           return False
   ```

1. 在 **DEPLOY** 區段中，選擇**部署**以更新函數的程式碼。

------
#### [ Node.js ]

**建立 Lambda 函式**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 執行下列動作，建立基本的 'Hello world' 函式：

   1. 選擇 **Create function (建立函數)**。

   1. 選取**從頭開始撰寫**。

   1. 針對**函數名稱**，請輸入 **myLambdaWebhook**。

   1. 針對**執行期**，選取 **nodejs24.x。**

   1. 選擇 **Create function (建立函數)**。

1. 在**程式碼來源**窗格中，複製並貼上以下項目來取代現有程式碼：

   ```
   import crypto from 'crypto';
   
   export const handler = async (event, context) => {
       // Get the webhook secret from environment variables
       const webhookSecret = process.env.WEBHOOK_SECRET;
   
       // Verify the webhook signature
       if (!verifySignature(event, webhookSecret)) {
           return {
               statusCode: 401,
               body: JSON.stringify({ error: 'Invalid signature' })
           };
       }
   
       try {
           // Parse the webhook payload
           const payload = JSON.parse(event.body);
   
           // Handle different event types
           const eventType = payload.type;
   
           switch (eventType) {
               case 'payment.success': {
                   // Handle successful payment
                   const orderId = payload.orderId;
                   console.log(`Processing successful payment for order ${orderId}`);
   
                   // Add your business logic here
                   // For example, update database, send notifications, etc.
                   break;
               }
   
               case 'payment.failed': {
                   // Handle failed payment
                   const orderId = payload.orderId;
                   console.log(`Processing failed payment for order ${orderId}`);
   
                   // Add your business logic here
                   break;
               }
   
               default:
                   console.log(`Received unhandled event type: ${eventType}`);
           }
   
           // Return success response
           return {
               statusCode: 200,
               body: JSON.stringify({ received: true })
           };
   
       } catch (error) {
           if (error instanceof SyntaxError) {
               // Handle JSON parsing errors
               return {
                   statusCode: 400,
                   body: JSON.stringify({ error: 'Invalid JSON payload' })
               };
           }
   
           // Handle all other errors
           console.error('Error processing webhook:', error);
           return {
               statusCode: 500,
               body: JSON.stringify({ error: 'Internal server error' })
           };
       }
   };
   
   // Verify the webhook signature using HMAC
   
   const verifySignature = (event, webhookSecret) => {
       try {
           // Get the signature from headers
           const signature = event.headers['x-webhook-signature'];
     
           if (!signature) {
               console.log('No signature found in headers:', event.headers);
               return false;
           }
     
           // Get the raw body (return an empty string if the body key doesn't exist)
           const body = event.body || '';
     
           // Create HMAC using the secret key
           const hmac = crypto.createHmac('sha256', webhookSecret);
           const expectedSignature = hmac.update(body).digest('hex');
     
           // Compare expected and received signatures
           const isValid = signature === expectedSignature;
           if (!isValid) {
               console.log(`Invalid signature. Received: ${signature}, Expected: ${expectedSignature}`);
               return false;
           }
           
           return true;
       } catch (error) {
           console.error('Error during signature verification:', error);
           return false;
       }
     };
   ```

1. 在 **DEPLOY** 區段中，選擇**部署**以更新函數的程式碼。

------

## 建立秘密金鑰
<a name="urls-webhook-tutorial-key"></a>

Lambda 函式若要驗證 Webhook 請求，會使用一個與呼叫應用程式共用的秘密金鑰。在此範例中，金鑰存放在環境變數中。但在生產應用程式中，請勿在函數程式碼中包含密碼等敏感資訊。反之，[請建立 AWS Secrets Manager 秘密](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html)，[然後使用 AWS 參數和秘密 Lambda 延伸](with-secrets-manager.md)來擷取 Lambda 函數中的登入資料。

**建立並儲存 Webhook 秘密金鑰**

1. 使用密碼編譯安全的隨機數字產生器，產生一個長的隨機字串。您可以使用下列以 Python 或 Node.js 編寫的程式碼片段來生成並列印 32 字元的秘密，也可以使用自己慣用的方法。

------
#### [ Python ]

**Example 產生秘密的程式碼**  

   ```
   import secrets
   webhook_secret = secrets.token_urlsafe(32)
   print(webhook_secret)
   ```

------
#### [ Node.js ]

**Example 產生秘密的程式碼 (ES 模組格式)**  

   ```
   import crypto from 'crypto';
   let webhookSecret = crypto.randomBytes(32).toString('base64');
   console.log(webhookSecret)
   ```

------

1. 執行下列動作，將產生的字串儲存為函式的環境變數：

   1. 在函式的**組態**索引標籤中，選取**環境變數**。

   1. 選擇**編輯**。

   1. 選擇 **Add environment variable** (新增環境變數)。

   1. 在**金鑰**欄位中，輸入 **WEBHOOK\$1SECRET**；接著在**值**欄位中，輸入上一個步驟中產生的秘密。

   1. 選擇**儲存**。

本教學課程後續將再次用到此金鑰來測試函式，因此請立即記錄下來。

## 建立函式 URL 端點
<a name="urls-webhook-tutorial-furl"></a>

使用 Lambda 函式 URL 為 Webhook 建立端點。由於您使用身分驗證類型 `NONE` 來建立具有公有存取權的端點，因此任何擁有 URL 的使用者都可以調用函式。若要進一步了解如何控制函式 URL 的存取權，請參閱[控制對 Lambda 函數 URL 的存取](urls-auth.md)。如果 Webhook 需要更進階的身分驗證選項，建議採用 API Gateway。

**建立函式 URL 端點**

1. 在函式的**組態**索引標籤中，選取**函式 URL**。

1. 選擇 **Create function URL** (建立函數 URL)。

1. 在**身分驗證類型**欄位中，選取 **NONE**。

1. 選擇**儲存**。

剛剛建立的函式 URL 端點會顯示在**函式 URL** 窗格中。複製端點，在教學課程後續部分使用。

## 在主控台中測試函式
<a name="urls-webhook-tutorial-test-console"></a>

在透過 URL 端點使用 HTTP 請求調用函式之前，請先在主控台中測試，確認程式碼如預期運作。

若要在主控台中驗證函式，需先使用之前在教學課程中產生的秘密，搭配以下測試用 JSON 承載資料計算 Webhook 簽章：

```
{
    "type": "payment.success", 
    "orderId": "1234",
    "amount": "99.99"
}
```

利用下列其中一個以 Python 或 Node.js 編寫的程式碼範例，並使用您自己的秘密來計算 Webhook 簽章。

------
#### [ Python ]

**計算 Webhook 簽章**

1. 將下列程式碼儲存為名為 `calculate_signature.py` 的檔案。將程式碼中的 Webhook 秘密取代為您自己的值。

   ```
   import secrets
   import hmac
   import json
   import hashlib
   
   webhook_secret = "arlbSDCP86n_1H90s0fL_Qb2NAHBIBQOyGI0X4Zay4M"
   
   body = json.dumps({"type": "payment.success", "orderId": "1234", "amount": "99.99"})
   
   signature = hmac.new(
               webhook_secret.encode('utf-8'),
               body.encode('utf-8'),
               hashlib.sha256
           ).hexdigest()
   
   print(signature)
   ```

1. 從儲存程式碼的同一目錄中執行下列命令來計算簽章。複製程式碼輸出的簽章。

   ```
   python calculate_signature.py
   ```

------
#### [ Node.js ]

**計算 Webhook 簽章**

1. 將下列程式碼儲存為名為 `calculate_signature.mjs` 的檔案。將程式碼中的 Webhook 秘密取代為您自己的值。

   ```
   import crypto from 'crypto';
   
   const webhookSecret = "arlbSDCP86n_1H90s0fL_Qb2NAHBIBQOyGI0X4Zay4M"
   const body = "{\"type\": \"payment.success\", \"orderId\": \"1234\", \"amount\": \"99.99\"}";
   
   let hmac = crypto.createHmac('sha256', webhookSecret);
   let signature = hmac.update(body).digest('hex');
   
   console.log(signature);
   ```

1. 從儲存程式碼的同一目錄中執行下列命令來計算簽章。複製程式碼輸出的簽章。

   ```
   node calculate_signature.mjs
   ```

------

現在，您可以在主控台中使用測試 HTTP 請求來測試函式程式碼。

**在主控台中測試函式**

1. 選取函式的**程式碼**索引標籤。

1. 在**測試事件**區段中，選擇**建立新測試事件**

1. **Event Name (事件名稱)** 輸入 **myEvent**。

1. 將下列項目複製並貼入**事件 JSON** 窗格中，取代現有的 JSON。將 Webhook 簽章取代為在上一個步驟中計算得出的值。

   ```
   {
     "headers": {
       "Content-Type": "application/json",
       "x-webhook-signature": "2d672e7a0423fab740fbc040e801d1241f2df32d2ffd8989617a599486553e2a"
     },
     "body": "{\"type\": \"payment.success\", \"orderId\": \"1234\", \"amount\": \"99.99\"}"
   }
   ```

1. 選擇**儲存**。

1. 選擇**調用**。

   您應該會看到類似下列的輸出：

------
#### [ Python ]

   ```
   Status: Succeeded
   Test Event Name: myEvent
   
   Response:
   {
     "statusCode": 200,
     "body": "{\"received\": true}"
   }
   
   Function Logs:
   START RequestId: 50cc0788-d70e-453a-9a22-ceaa210e8ac6 Version: $LATEST
   Processing successful payment for order 1234
   END RequestId: 50cc0788-d70e-453a-9a22-ceaa210e8ac6
   REPORT RequestId: 50cc0788-d70e-453a-9a22-ceaa210e8ac6	Duration: 1.55 ms	Billed Duration: 2 ms	Memory Size: 128 MB	Max Memory Used: 36 MB	Init Duration: 136.32 ms
   ```

------
#### [ Node.js ]

   ```
   Status: Succeeded
   Test Event Name: myEvent
   
   Response:
   {
     "statusCode": 200,
     "body": "{\"received\":true}"
   }
   
   Function Logs:
   START RequestId: e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4 Version: $LATEST
   2025-01-10T18:05:42.062Z	e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4	INFO	Processing successful payment for order 1234
   END RequestId: e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4
   REPORT RequestId: e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4	Duration: 60.10 ms	Billed Duration: 61 ms	Memory Size: 128 MB	Max Memory Used: 72 MB	Init Duration: 174.46 ms
   
   Request ID: e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4
   ```

------

## 使用 HTTP 請求測試函式
<a name="urls-webhook-tutorial-test-curl"></a>

使用 curl 命令列工具來測試 Webhook 端點。

**使用 HTTP 請求測試函式**

1. 在終端或 Shell 程式中，執行下列 curl 命令。將 URL 取代為您自己的函式 URL 端點的值，並將 Webhook 簽章取代為您使用自己的秘密金鑰計算得出的簽章。

   ```
   curl -X POST https://ryqgmbx5xjzxahif6frvzikpre0bpvpf.lambda-url.us-west-2.on.aws/ \
   -H "Content-Type: application/json" \
   -H "x-webhook-signature: d5f52b76ffba65ff60ea73da67bdf1fc5825d4db56b5d3ffa0b64b7cb85ef48b" \
   -d '{"type": "payment.success", "orderId": "1234", "amount": "99.99"}'
   ```

   您應該會看到下列輸出：

   ```
   {"received": true}
   ```

1. 執行下列動作，檢查函式的 CloudWatch 日誌，確認其正確剖析了承載：

   1. 在 Amazon CloudWatch 主控台中，開啟[日誌群組](https://console.aws.amazon.com/cloudwatch/home#logsV2:log-groups)頁面。

   1. 選取函式的日誌群組 (`/aws/lambda/myLambdaWebhook`)。

   1. 選取最新的日誌串流。

      您應該會在函式日誌中看到類似如下的輸出：

------
#### [ Python ]

      ```
      Processing successful payment for order 1234
      ```

------
#### [ Node.js ]

      ```
      2025-01-10T18:05:42.062Z e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4 INFO Processing successful payment for order 1234
      ```

------

1. 執行下列 curl 命令，確認程式碼偵測到無效的簽章。將 URL 取代為您自己的函式 URL 端點。

   ```
   curl -X POST https://ryqgmbx5xjzxahif6frvzikpre0bpvpf.lambda-url.us-west-2.on.aws/ \
   -H "Content-Type: application/json" \
   -H "x-webhook-signature: abcdefg" \
   -d '{"type": "payment.success", "orderId": "1234", "amount": "99.99"}'
   ```

   您應該會看到下列輸出：

   ```
   {"error": "Invalid signature"}
   ```

## 清除您的資源
<a name="urls-webhook-tutorial-cleanup"></a>

除非您想要保留為此教學課程建立的資源，否則您現在便可刪除。透過刪除您不再使用 AWS 的資源，您可以避免不必要的 費用 AWS 帳戶。

**若要刪除 Lambda 函數**

1. 開啟 Lambda 主控台中的 [函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇您建立的函數。

1. 選擇 **Actions** (動作)、**Delete** (刪除)。

1. 在文字輸入欄位中輸入 **confirm**，然後選擇**刪除**。

當您在主控台中建立 Lambda 函式時，Lambda 也會為函式建立[執行角色](lambda-intro-execution-role.md)。

**刪除執行角色**

1. 開啟 IAM 主控台中的 [角色頁面](https://console.aws.amazon.com/iam/home#/roles) 。

1. 選取 Lambda 建立的執行角色。角色名稱具有格式 `myLambdaWebhook-role-<random string>`。

1. 選擇 **刪除**。

1. 在文字輸入欄位中輸入角色的名稱，然後選擇**刪除**。