

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

# HTTP 攔截器
<a name="interceptors"></a>

 您可以使用攔截器來勾結 API 請求和回應的執行。攔截器是開放式機制，其中 SDK 會呼叫您編寫的程式碼，將行為注入請求/回應生命週期。如此一來，您就可以修改處理中的請求、除錯請求處理、檢視例外狀況等等。

## 攔截器與中介軟體
<a name="interceptors-vs-middleware"></a>

 適用於 Go 的 AWS SDK v2 同時提供攔截器和中介軟體，以自訂請求處理。雖然兩者都有類似用途，但它們是專為不同的對象和使用案例而設計：
+  **攔截器**是專為想要使用簡單、著重於 HTTP 的 API 自訂請求/回應處理的 SDK 使用者而設計。它們在請求生命週期中提供特定的掛接點，並直接使用 HTTP 請求和回應。
+  **中介軟體**是更進階、傳輸無關的系統，主要由 SDK 在內部使用。雖然功能強大，但中介軟體需要更深入的 SDK 內部知識，並涉及更複雜的界面。

 在常見使用案例中，攔截器相較於中介軟體的主要優勢：
+  以 **HTTP 為重心**：攔截器可直接處理 HTTP 請求和回應，無需檢查中介軟體所需的傳輸類型。
+  **更簡單的界面**：每個攔截器勾點都有特定的聚焦界面，而不是通用中介軟體模式。
+  **更清晰的執行模型**：攔截器在請求生命週期中明確定義的點執行，而無需了解中介軟體堆疊排序。

**注意**  
 攔截器建置在現有的中介軟體系統之上，因此兩者可以共存於相同的應用程式中。中介軟體仍然適用於需要傳輸無關行為或複雜堆疊操作的進階使用案例。

## 可用的攔截器掛鉤
<a name="interceptor-hooks"></a>

 適用於 Go 的 AWS SDK v2 在請求生命週期的各個階段提供攔截器掛鉤。每個勾點對應至您可以實作的特定界面：
+  `BeforeExecution` - 在操作執行期間呼叫的第一個勾點 
+  `BeforeSerialization` - 將輸入訊息序列化為傳輸請求之前 
+  `AfterSerialization` - 將輸入訊息序列化為傳輸請求之後 
+  `BeforeRetryLoop` - 進入重試迴圈之前 
+  `BeforeAttempt` - 在重試迴圈中呼叫的第一個勾點 
+  `BeforeSigning` - 簽署傳輸請求之前 
+  `AfterSigning` - 簽署傳輸請求後 
+  `BeforeTransmit` - 傳送傳輸請求之前 
+  `AfterTransmit` - 收到傳輸回應後 
+  `BeforeDeserialization` - 傳輸回應還原序列化之前 
+  `AfterDeserialization` - 取消封送傳輸回應之後 
+  `AfterAttempt` - 在重試迴圈中呼叫的最後一個勾點 
+  `AfterExecution` - 操作執行期間呼叫的最後一個勾點 

 您可以在單一攔截器中實作多個界面，以掛鉤至請求生命週期的多個階段。

## 攔截器註冊
<a name="interceptor-registration"></a>

 您可以在建構服務用戶端或覆寫特定操作的組態時註冊攔截器。註冊會因您希望攔截器套用到用戶端的所有操作或僅套用特定操作而有所不同。

 攔截器是透過攔截器登錄檔進行管理，該登錄檔提供新增和移除攔截器的方法。下列範例顯示簡單的攔截器，在簽署程序之前將 AWS X-Ray 追蹤 ID 標頭新增至傳出請求：

```
type recursionDetection struct{}

func (recursionDetection) BeforeSigning(ctx context.Context, in *smithyhttp.InterceptorContext) error {
    if traceID := os.Getenv("_X_AMZN_TRACE_ID"); traceID != "" {
        in.Request.Header.Set("X-Amzn-Trace-Id", traceID)
    }
    return nil
}

// use it on the client
svc := s3.NewFromConfig(cfg, func(o *s3.Options) {
    o.Interceptors.AddBeforeSigning(recursionDetection{})
})
```

 攔截器登錄檔會新增至用戶端選項，以啟用每個操作攔截器組態：

```
// ... or use it per-operation
s3.ListBuckets(context.Background(), &s3.ListBucketsInput{
}, func(o *s3.Options) {
   o.Interceptors.AddBeforeSigning(recursionDetection{})
})
```

## 全域攔截器組態
<a name="interceptor-global-config"></a>

 您也可以使用 `config.LoadDefaultConfig`函數搭配每個攔截器類型的適當`With*`選項，全域註冊攔截器。這會將攔截器套用至從該組態建立的所有 AWS 服務用戶端：

```
type myExecutionInterceptor struct{}

func (*myExecutionInterceptor) AfterExecution(ctx context.Context, in *smithyhttp.InterceptorContext) error {
    // Add your custom logic here
    return nil
}

cfg, err := config.LoadDefaultConfig(context.Background(),
    config.WithAfterExecution(&myExecutionInterceptor{}))
if err != nil {
    panic(err)
}

// every service client created from the above config
// will include this interceptor
svc := s3.NewFromConfig(cfg)
```