

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

# 設定軟體開發套件
<a name="configure-gosdk"></a>

 在 適用於 Go 的 AWS SDK V2 中，您可以設定服務用戶端的常見設定，例如記錄器、日誌層級和重試組態。大多數設定都是選用的。不過，您必須為每個服務用戶端指定 AWS 區域和您的登入資料。SDK 使用這些值將請求傳送至正確的區域，並使用正確的登入資料簽署請求。您可以在程式碼中或透過執行環境以程式設計方式指定這些值。

## 載入 AWS 共用組態檔案
<a name="loading-aws-shared-configuration"></a>

 有多種方式可初始化服務 API 用戶端，但以下是建議使用者使用的最常見模式。

 若要設定 SDK 以使用 AWS 共用組態檔案，請使用下列程式碼：

```
import (
  "context"
  "log"
  "github.com/aws/aws-sdk-go-v2/config"
)

// ...

cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
  log.Fatalf("failed to load configuration, %v", err)
}
```

 `config.LoadDefaultConfig(context.TODO())` 將使用 AWS 共用組態來源建構 [aws.Config](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Config)。這包括設定登入資料提供者、設定 AWS 區域，以及載入服務特定組態。服務用戶端可以使用載入的 建構`aws.Config`，提供建構用戶端的一致模式。

 如需 AWS 共用組態檔案的詳細資訊，請參閱《 AWS SDKs和工具參考指南》中的[組態](https://docs.aws.amazon.com/sdkref/latest/guide/creds-config-files.html)。

## 指定 AWS 區域
<a name="specifying-the-aws-region"></a>

 當您指定 區域時，您可以指定傳送請求的位置，例如 `us-west-2`或 `us-east-2`。如需每個服務的區域清單，請參閱《》中的[服務端點和配額](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html) Amazon Web Services 一般參考。

 軟體開發套件沒有預設區域。若要指定區域：
+  將`AWS_REGION`環境變數設定為預設區域。
+  載入組態`config.LoadDefaultConfig`時，使用 [config.WithRegion](https://github.com/aws/aws-sdk-go-v2/blob/config/v0.2.2/config/provider.go#L127) 明確地將區域設定為 的引數。

 檢閱：如果您使用所有這些技術設定區域，開發套件會使用您明確指定的區域。

### 使用環境變數設定區域
<a name="configure-region-with-environment-variable"></a>

#### Linux、macOS 或 Unix
<a name="linux-macos-or-unix"></a>

```
export AWS_REGION=us-west-2
```

#### Windows
<a name="windows"></a>

```
set AWS_REGION=us-west-2
```

### 以程式設計方式指定區域
<a name="specify-region-programmatically"></a>

```
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-west-2"))
```

## 指定憑證
<a name="specifying-credentials"></a>

 適用於 Go 的 AWS SDK 需要登入資料 （存取金鑰和私密存取金鑰） 才能簽署請求 AWS。您可以根據您的特定使用案例，在多個位置指定您的登入資料。如需取得登入資料的資訊，請參閱 [開始使用 適用於 Go 的 AWS SDK](getting-started.md)。

 當您使用 初始化`aws.Config`執行個體時`config.LoadDefaultConfig`，開發套件會使用其預設登入資料鏈來尋找 AWS 登入資料。此預設登入資料鏈結會依下列順序尋找登入資料：

1.  環境變數.

   1.  靜態登入資料 (`AWS_ACCESS_KEY_ID`、`AWS_SECRET_ACCESS_KEY`、`AWS_SESSION_TOKEN`) 

   1.  Web 身分字符 (`AWS_WEB_IDENTITY_TOKEN_FILE`) 

1.  共用組態檔案。

   1.  SDK 預設為位於您電腦主`.aws`資料夾中 資料夾下的 `credentials` 檔案。

   1.  SDK 預設為位於您電腦主`.aws`資料夾中 資料夾下的 `config` 檔案。

1.  如果您的應用程式使用 Amazon ECS 任務定義或 RunTask API 操作，則為任務使用 IAM 角色。

1.  如果您的應用程式在 Amazon EC2 執行個體上執行，則為 Amazon EC2 的 IAM 角色。

 SDK 會自動偵測並使用內建提供者，而不需要手動設定。例如，如果您將 IAM 角色用於 Amazon EC2 執行個體，您的應用程式會自動使用執行個體的登入資料。您不需要在應用程式中手動設定登入資料。

 根據最佳實務， AWS 建議您依下列順序指定登入資料：

1.  如果您的應用程式使用 Amazon ECS 任務定義或 RunTask API 操作，請使用任務的 IAM 角色。

1.  將 IAM 角色用於 Amazon EC2 （如果您的應用程式在 Amazon EC2 執行個體上執行）。

    IAM 角色在執行個體上提供應用程式臨時安全登入資料來 AWS 呼叫 。IAM 角色提供在多個 Amazon EC2 執行個體上分佈和管理登入資料的簡單方法。

1.  使用共用的登入資料或組態檔案。

    登入資料和組態檔案會與其他 AWS SDKs和 共用 AWS CLI。作為安全最佳實務，建議使用登入資料檔案來設定敏感值，例如存取金鑰 IDs和私密金鑰。以下是每個這些檔案的[格式要求](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html)。

1.  使用環境變數。

    如果您在 Amazon EC2 執行個體以外的機器上執行開發工作，設定環境變數非常有用。

### 任務的 IAM 角色
<a name="iam-roles-for-tasks"></a>

 如果您的應用程式使用 Amazon ECS 任務定義或`RunTask`操作，請使用[任務的 IAM 角色](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html)來指定可由任務中的容器使用的 IAM 角色。

### Amazon EC2 執行個體的 IAM 角色
<a name="iam-roles-for-ec2-instances"></a>

 如果您在 Amazon EC2 執行個體上執行應用程式，請使用執行個體的 [IAM 角色](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)取得臨時安全登入資料來呼叫 AWS。

 如果您已將執行個體設定為使用 IAM 角色，軟體開發套件會自動將這些登入資料用於您的應用程式。您不需要手動指定這些登入資料。

### 共用登入資料和組態
<a name="shared-credentials-and-configuration"></a>

 共用的登入資料和組態檔案可用於在 AWS SDKs 和其他工具之間共用常見的組態。如果您將不同的登入資料用於不同的工具或應用程式，即可在同一個組態檔案中使用*描述檔*設定多個存取金鑰。

 您可以使用 提供多個登入資料或組態檔案位置`config.LoadOptions`，根據預設，軟體開發套件會載入存放在 中提及的預設位置的檔案[指定憑證](#specifying-credentials)。

```
import (
    "context"
    "github.com/aws/aws-sdk-go-v2/config"    
)

// ...

cfg , err := config.LoadDefaultConfig(context.TODO(), 
    config.WithSharedCredentialsFiles(
    []string{"test/credentials", "data/credentials"},
    ), 
    config.WithSharedConfigFiles(
        []string{"test/config", "data/config"},
    )   
)
```

 使用共用登入資料和組態檔案時，如果指定了重複的設定檔，則會合併這些設定檔以解析設定檔。如果發生合併衝突，

1.  如果在相同的登入資料/組態檔案中指定了重複的設定檔，則後者設定檔中指定的設定檔屬性優先。

1.  如果跨多個登入資料檔案或多個組態檔案指定了重複的設定檔，則會根據檔案輸入至 的順序來解析設定檔屬性`config.LoadOptions`。後者檔案中的設定檔屬性優先。

1.  如果 設定檔同時存在於登入資料檔案和組態檔案中，則登入資料檔案屬性優先。

 如有需要，您可以在 `LogConfigurationWarnings`上啟用 `config.LoadOptions` 並記錄設定檔解析步驟。

#### 建立登入資料檔案
<a name="creating-the-credentials-file"></a>

 如果您沒有共用的登入資料檔案 (`.aws/credentials`)，您可以使用任何文字編輯器在主目錄中建立一個。將下列內容新增至您的登入資料檔案，以您的登入資料取代 *<YOUR\$1ACCESS\$1KEY\$1ID>* 和 *<YOUR\$1SECRET\$1ACCESS\$1KEY>*。

```
[default]
aws_access_key_id = <YOUR_ACCESS_KEY_ID>
aws_secret_access_key = <YOUR_SECRET_ACCESS_KEY>
```

 `[default]` 標題會定義預設設定檔的登入資料，除非您將其設定為使用另一個設定檔，否則軟體開發套件將使用該登入資料。

 您也可以將工作階段字符新增至您的設定檔，以使用臨時安全登入資料，如下列範例所示：

```
[temp]
aws_access_key_id = <YOUR_TEMP_ACCESS_KEY_ID>
aws_secret_access_key = <YOUR_TEMP_SECRET_ACCESS_KEY>
aws_session_token = <YOUR_SESSION_TOKEN>
```

 登入資料檔案中非預設設定檔的區段名稱不得以字詞 開頭`profile`。您可以在 [AWS SDKs和工具參考指南](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html#file-format-creds)中閱讀更多資訊。

#### 建立 Config 檔案
<a name="creating-the-config-file"></a>

 如果您沒有共用的登入資料檔案 (`.aws/config`)，您可以使用任何文字編輯器在主目錄中建立一個。將下列內容新增至您的組態檔案，將 *<REGION>* 取代為所需的區域。

```
[default]
region = <REGION>
```

 `[default]` 標題會定義預設描述檔的組態，除非您將其設定為使用另一個描述檔，否則軟體開發套件將使用它。

 您可以使用具名設定檔，如下列範例所示：

```
[profile named-profile]
region = <REGION>
```

 組態檔案中非預設設定檔的區段名稱必須一律以單字 開頭`profile`，後面接著預期的設定檔名稱。您可以在 [AWS SDKs和工具參考指南](https://docs.aws.amazon.com/credref/latest/refdocs/file-format.html#file-format-config)中閱讀更多資訊。

#### 指定設定檔
<a name="specifying-profiles"></a>

 您可以透過將每組存取金鑰與設定檔建立關聯，在相同的組態檔案中包含多個存取金鑰。例如，在您的登入資料檔案中，您可以宣告多個設定檔，如下所示。

```
[default]
aws_access_key_id = <YOUR_DEFAULT_ACCESS_KEY_ID>
aws_secret_access_key = <YOUR_DEFAULT_SECRET_ACCESS_KEY>

[test-account]
aws_access_key_id = <YOUR_TEST_ACCESS_KEY_ID>
aws_secret_access_key = <YOUR_TEST_SECRET_ACCESS_KEY>

[prod-account]
; work profile
aws_access_key_id = <YOUR_PROD_ACCESS_KEY_ID>
aws_secret_access_key = <YOUR_PROD_SECRET_ACCESS_KEY>
```

 依預設，軟體開發套件會檢查 `AWS_PROFILE` 環境變數來判斷要使用哪個設定檔。如果未設定`AWS_PROFILE`變數，則 SDK 會使用 `default`設定檔。

 有時，您可能想要在應用程式中使用不同的設定檔。例如，您想要將`test-account`登入資料與`myapp`應用程式搭配使用。您可以使用下列命令來使用此設定檔：

```
$ AWS_PROFILE=test-account myapp
```

 您也可以使用指示 SDK 在呼叫 `os.Setenv("AWS_PROFILE", "test-account")`之前呼叫 來選取設定檔`config.LoadDefaultConfig`，或傳遞明確設定檔做為引數，如下列範例所示：

```
cfg, err := config.LoadDefaultConfig(context.TODO(), 
    config.WithSharedConfigProfile("test-account"))
```

**注意**  
如果您在環境變數中指定登入資料，無論指定哪個設定檔，開發套件一律都會使用這些登入資料。

### 環境變數
<a name="environment-variables"></a>

 根據預設，軟體開發套件會偵測您環境中設定的 AWS 登入資料，並使用它們來簽署請求 AWS。如此一來，您就不需要在應用程式中管理登入資料。

 SDK 會在下列環境變數中尋找登入資料：
+  `AWS_ACCESS_KEY_ID` 
+  `AWS_SECRET_ACCESS_KEY` 
+  `AWS_SESSION_TOKEN` (選用) 

 下列範例示範如何設定環境變數。

#### Linux、OS X，或 Unix
<a name="linux-os-x-or-unix"></a>

```
$ export AWS_ACCESS_KEY_ID=YOUR_AKID
$ export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
$ export AWS_SESSION_TOKEN=TOKEN
```

#### Windows
<a name="windows-1"></a>

```
> set AWS_ACCESS_KEY_ID=YOUR_AKID
> set AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
> set AWS_SESSION_TOKEN=TOKEN
```

### 以程式設計方式指定登入資料
<a name="specify-credentials-programmatically"></a>

 `config.LoadDefaultConfig` 可讓您在載入共用組態來源時提供明確的 [aws.CredentialProvider](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#CredentialsProvider)。若要在載入共用組態時傳遞明確的登入資料提供者，請使用 [config.WithCredentialsProvider](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config#WithCredentialsProvider)。例如，如果 `customProvider`參考`aws.CredentialProvider`實作的執行個體，它可以在組態載入期間傳遞，如下所示：

```
cfg, err := config.LoadDefaultConfig(context.TODO(), 
    config.WithCredentialsProvider(customProvider))
```

 如果您明確提供登入資料，如本範例所示，開發套件只會使用這些登入資料。

**注意**  
傳遞至 或由 傳回的所有登入資料提供者`LoadDefaultConfig`都會自動包裝在 [CredentialsCache](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#CredentialsCache) 中。這可啟用並行安全的快取和登入資料輪換。如果您`aws.Config`直接在 上明確設定提供者，您還必須使用 [NewCredentialsCache](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#NewCredentialsCache) 明確包裝具有此類型的提供者。

#### 靜態登入資料
<a name="static-credentials"></a>

 您可以使用登入資料在應用程式中硬式編碼[登入資料。NewStaticCredentialsProvider](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials#NewStaticCredentialsProvider) 登入資料提供者可明確設定要使用的存取金鑰。例如：

```
cfg, err := config.LoadDefaultConfig(context.TODO(), 
    config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider("AKID", "SECRET_KEY", "TOKEN")),
)
```

**警告**  
 請勿在應用程式中內嵌登入資料。僅將此方法用於測試目的。

#### 單一登入登入資料
<a name="single-sign-on-credentials"></a>

 開發套件提供登入資料提供者，以使用 擷取臨時 AWS 登入資料 AWS IAM Identity Center。使用 AWS CLI，您可以使用 AWS 存取入口網站進行身分驗證，並授權存取臨時 AWS 登入資料。然後，您將應用程式設定為載入單一登入 (SSO) 設定檔，開發套件會使用 SSO 登入資料來擷取臨時 AWS 登入資料，該登入資料將在過期時自動續約。如果您的 SSO 憑證過期，您必須再次使用 登入 IAM Identity Center 帳戶，以明確續約憑證 AWS CLI。

 例如，您可以建立設定檔、`dev-profile`、使用 驗證和授權該設定檔 AWS CLI，以及設定您的應用程式，如下所示。

1.  首先建立 `profile`和 `sso-session` 

```
[profile dev-profile]
sso_session = dev-session
sso_account_id = 012345678901
sso_role_name = Developer
region = us-east-1

[sso-session dev-session]
sso_region = us-west-2
sso_start_url = https://company-sso-portal.awsapps.com/start
sso_registration_scopes = sso:account:access
```

1.  使用 登入 AWS CLI 以驗證和授權 SSO 設定檔。

```
$ aws --profile dev-profile sso login 
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:

https://device.sso.us-west-2.amazonaws.com/

Then enter the code:

ABCD-EFGH
Successully logged into Start URL: https://company-sso-portal.awsapps.com/start
```

1.  接著，將應用程式設定為使用 SSO 設定檔。

```
import "github.com/aws/aws-sdk-go-v2/config"

// ...

cfg, err := config.LoadDefaultConfig(
    context.Background(),
    config.WithSharedConfigProfile("dev-profile"),
)
if err != nil {
    return err
}
```

 如需設定 SSO 設定檔和使用 驗證的詳細資訊， AWS CLI 請參閱《 使用者指南》中的[設定 AWS CLI 要使用 AWS IAM Identity Center](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html)的 AWS CLI 。如需以程式設計方式建構 SSO 憑證提供者的詳細資訊，請參閱 [ssocreds](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials/ssocreds) API 參考文件。

#### 登入憑證
<a name="login-credentials"></a>

您可以使用現有的 AWS 管理主控台登入憑證，以程式設計方式存取 AWS 服務。在瀏覽器型身分驗證流程之後， AWS 會產生臨時登入資料，可用於 CLI AWS Tools for PowerShell 和 AWS SDKs AWS 等本機開發工具。此功能可簡化設定和管理 AWS CLI 登入資料的程序，尤其是如果您偏好互動式身分驗證，而不是管理長期存取金鑰。

1. 使用 CLI AWS 啟動登入流程，並遵循瀏覽器提示。在此範例中，我們會將登入工作階段儲存至新的設定檔 **dev-profile**，但這是選用的。

   ```
   $ aws --profile dev-profile login
   ```

1. （選用） 檢查您的 AWS 共用組態檔案，以確認工作階段已建立。

   ```
   [profile dev-profile]
   login_session = arn:aws:sts::account id>:role
   ```

1. 接著，將應用程式設定為使用登入設定檔。

   ```
   import "github.com/aws/aws-sdk-go-v2/config"
   
   // ...
   
   cfg, err := config.LoadDefaultConfig(
       context.Background(),
       // only necessary if login session is saved to a non-default profile
       config.WithSharedConfigProfile("dev-profile"),
   )
   if err != nil {
       return err
   }
   ```

如需設定登入設定檔及使用 AWS CLI 驗證的詳細資訊，請參閱[使用主控台登入資料進行 AWS 本機開發的登入](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sign-in.html)。

#### 其他登入資料提供者
<a name="other-credentials-providers"></a>

 SDK 提供在登入資料模組中擷取[登入](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials)資料的其他方法。例如，您可以從 擷取臨時安全登入資料 AWS Security Token Service ，或從加密儲存擷取登入資料。

 **可用的登入資料提供者**：
+  [ec2rolecreds](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds) – 透過 Amazon EC2 IMDS 從 Amazon EC2 執行個體角色擷取登入資料。
+  [endpointcreds](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds) – 從任意 HTTP 端點擷取登入資料。
+  [processcreds](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials/processcreds) – 從外部程序擷取登入資料，該程序將由主機環境的 shell 叫用。
+  [stscreds](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials/stscreds) – 從 擷取登入資料 AWS STS 

# 設定身分驗證
<a name="configure-auth"></a>

 適用於 Go 的 AWS SDK 提供設定身分驗證行為服務的功能。在大多數情況下，預設組態就已足夠，但設定自訂身分驗證允許使用發行前服務功能等其他行為。

## 定義
<a name="definitions"></a>

 本節提供 中身分驗證元件的高階描述 適用於 Go 的 AWS SDK。

### AuthScheme
<a name="authscheme"></a>

 [AuthScheme](https://pkg.go.dev/github.com/aws/smithy-go/transport/http#AuthScheme) 是定義工作流程的界面，開發套件會透過此工作流程擷取發起人身分並將其連接至操作請求。

 驗證方案使用下列元件，以下進一步詳細說明：
+  識別方案的唯一 ID 
+  身分解析程式，會傳回用於簽署程序的發起人身分 （例如您的 AWS 登入資料） 
+  簽署者，執行將發起人身分實際注入操作的傳輸請求 （例如 `Authorization` HTTP 標頭） 

 每個服務用戶端選項都包含 `AuthSchemes` 欄位，預設會填入該服務支援的身分驗證方案清單。

### AuthSchemeResolver
<a name="authschemeresolver"></a>

 每個服務用戶端選項都包含 `AuthSchemeResolver` 欄位。此界面是 SDK 呼叫的 API，用於判斷每個操作的可能身分驗證選項。

**重要**  
 驗證方案解析程式不會指定使用哪個驗證方案。它會傳回*可使用*的方案清單 (「選項」)，最終方案是透過[此處](#auth-scheme-resolution-workflow)所述的固定演算法選取。

### 選項
<a name="option"></a>

 [選項](https://pkg.go.dev/github.com/aws/smithy-go/auth#Option)代表可能的身分驗證選項`ResolverAuthSchemes`，從對 的呼叫傳回。

 選項包含三組資訊：
+  代表可能方案的 ID 
+  要提供給方案身分解析程式的不透明屬性集 
+  要提供給方案簽署者的不透明屬性集 

#### 屬性的備註
<a name="a-note-on-properties"></a>

 對於 99% 的使用案例，發起人不需要擔心身分解析和簽署的不透明屬性。開發套件會提取每個方案的必要屬性，並將其傳遞至開發套件中公開的強類型界面。例如，服務的預設身分驗證解析程式會編碼 SigV4 選項，讓簽署名稱和區域的簽署者屬性具有，當選取 SigV4 時，其值會傳遞給用戶端設定的 [v4.HTTPSigner ](https://pkg.go.dev/github.com/aws/smithy-go/auth#Option)實作。

### Identity
<a name="identity"></a>

 [Identity](https://pkg.go.dev/github.com/aws/smithy-go/auth#Identity) 是 SDK 發起人身分的抽象表示。

 開發套件中使用的最常見身分類型是一組 `aws.Credentials`。對於大多數使用案例，發起人不需要將自己與 `Identity`視為抽象，並且可以直接使用具體類型。

**注意**  
 為了保持回溯相容性並防止 API 混淆， AWS 開發套件特定的身分類型`aws.Credentials`不會直接滿足`Identity`界面。此映射會在內部處理。

### IdentityResolver
<a name="identityresolver"></a>

 [IdentityResolver](https://pkg.go.dev/github.com/aws/smithy-go/auth#IdentityResolver) 是擷取 的界面`Identity`。

 軟體開發套件中`IdentityResolver`存在以強類型形式存在的具體版本 （例如 [aws.CredentialsProvider](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#CredentialsProvider))，軟體開發套件會在內部處理此映射。

 發起人在定義外部身分驗證機制時，只需要直接實作`IdentityResolver`界面。

### Signer
<a name="signer"></a>

 [Signer](https://pkg.go.dev/github.com/aws/smithy-go/transport/http#Signer) 是請求以擷取呼叫者 補充的界面`Identity`。

 軟體開發套件會以強類型形式 （例如 [v4.HTTPSigner](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/signer/v4#HTTPSigner)) `Signer` 存在於軟體開發套件中的具體版本，軟體開發套件會在內部處理此映射。

 發起人只需要在定義外部身分驗證機制時直接實作`Signer`界面。

### AuthResolverParameters
<a name="authresolverparameters"></a>

 每個服務都會接受一組特定的輸入，這些輸入會傳遞至其解析度函數，在每個服務套件中定義為 `AuthResolverParameters`。

 基本解析程式參數如下：


|  name  |  type  |  description  | 
| --- | --- | --- | 
|  Operation  |  string  |  要叫用的 操作名稱。 | 
|  Region  |  string  |  用戶端 AWS 的區域。僅適用於使用 SigV4【A】 的服務。 | 

 如果您要實作自己的解析程式，則永遠不需要建構自己的參數執行個體。開發套件會依請求取得這些值，並將其傳遞給您的實作。

## 驗證方案解析工作流程
<a name="auth-scheme-resolution-workflow"></a>

 當您透過 SDK 呼叫 AWS 服務操作時，請求序列化後會發生下列動作序列：

1.  軟體開發套件會呼叫用戶端的 `AuthSchemeResolver.ResolveAuthSchemes()` API，視需要取得輸入參數，以取得操作的可能[選項](https://pkg.go.dev/github.com/aws/smithy-go/auth#Option)清單。

1.  SDK 會逐一查看該清單，然後選取第一個符合下列條件的方案。
   +  具有相符 ID 的方案存在於用戶端自己的`AuthSchemes`清單中 
   +  方案的身分解析程式存在於 （非`nil`) 用戶端的選項上 （透過方案的 `GetIdentityResolver`方法檢查，對上述具體身分解析程式類型的映射會在內部處理） (1) 

1.  假設已選取可行的方案，開發套件會叫用其 `GetIdentityResolver()` API 來擷取發起人的身分。例如，內建的 SigV4 驗證機制會在內部映射到用戶端的`Credentials`提供者。

1.  SDK 會呼叫身分解析程式的 `GetIdentity()`（例如`aws.CredentialProvider.Retrieve()`，適用於 SigV4)。

1.  SDK 會呼叫端點解析程式的 `ResolveEndpoint()`，以尋找請求的端點。端點可能包含會影響簽署程序的其他中繼資料 （例如 S3 Object Lambda 的唯一簽署名稱）。

1.  SDK 會呼叫身分驗證機制的 `Signer()` API 來擷取其簽署者，並使用其 `SignRequest()` API 來簽署具有先前擷取的呼叫者身分的請求。

 (1) 如果 SDK 在清單中遇到匿名選項 (ID`smithy.api#noAuth`)，則會自動選取，因為沒有對應的身分解析程式。

## 原生支援的 `AuthScheme`
<a name="natively-supported-authschemes"></a>

 原生支援下列身分驗證方案 適用於 Go 的 AWS SDK。


|  名稱  |  結構描述 ID  |  身分解析程式  |  Signer  |  備註  | 
| --- | --- | --- | --- | --- | 
|  [SigV4](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html)  |  aws.auth\$1sigv4  |  [aws.CredentialsProvider](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Credentials)  |  [v4.HTTPSigner](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/signer/v4#Signer)  |  大多數 AWS 服務操作的目前預設值。 | 
|  SigV4A  |  aws.auth\$1sigv4a  |  aws.CredentialsProvider  |  N/A  |  SigV4A 用量目前受到限制，簽署者實作為內部。請參閱此[公告](https://github.com/aws/aws-sdk-go-v2/discussions/2812)，了解新的選擇加入模組 aws-http-auth，該模組公開用於簽署 HTTP 請求的一般用途 APIs。 | 
|  SigV4Express  |  com.amazonaws.s3\$1sigv4express  |  [s3.ExpressCredentialsProvider](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/s3#ExpressCredentialsProvider)  |  v4.HTTPSigner  |  用於 [Express One Zone](https://aws.amazon.com/s3/storage-classes/express-one-zone/)。 | 
|  HTTP 承載器  |  smithy.api\$1httpBearerAuth  |  [smithybearer.TokenProvider](https://pkg.go.dev/github.com/aws/smithy-go/auth/bearer#TokenProvider)  |  [smithybearer.Signer](https://pkg.go.dev/github.com/aws/smithy-go/auth/bearer#Signer)  |  由 [codecatalyst](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/codecatalyst) 使用。 | 
|  匿名  |  smithy.api\$1noAuth  |  N/A  |  無  |  無身分驗證 - 不需要身分，且請求未簽署或驗證。 | 

### 身分組態
<a name="identity-configuration"></a>

 在 中 適用於 Go 的 AWS SDK，身分驗證方案的身分元件是在 SDK 用戶端 中設定`Options`。軟體開發套件會自動為呼叫 操作時所選取的配置，挑選並使用這些元件的值。

**注意**  
 基於回溯相容性的原因，如果未設定身分解析程式，開發套件會隱含允許使用匿名身分驗證機制。這可以透過將用戶端 上的所有身分解析程式設定為 `Options``nil`(sigv4 身分解析程式也可以設定為 `aws.AnonymousCredentials{}`) 來手動實現。

### 簽署者組態
<a name="signer-configuration"></a>

 在 中 適用於 Go 的 AWS SDK，身分驗證方案的簽署者元件是在 SDK 用戶端 中設定`Options`。軟體開發套件會自動為呼叫 操作時所選取的配置，挑選並使用這些元件的值。不需要額外的組態。

#### 自訂身分驗證方案
<a name="custom-auth-scheme"></a>

 為了定義自訂身分驗證方案並將其設定為使用，發起人必須執行下列動作：

1.  定義 [AuthScheme](https://pkg.go.dev/github.com/aws/smithy-go/transport/http#AuthScheme) 實作 

1.  在 SDK 用戶端的`AuthSchemes`清單上註冊方案 

1.  檢測 SDK 用戶端的 `AuthSchemeResolver`，在適用的情況下`Option`使用結構描述的 ID 傳回身分驗證 

**警告**  
 下列服務具有唯一或自訂的身分驗證行為。如果您需要自訂身分驗證行為，建議您委派 給預設實作，並據此進行包裝：  


|  服務  |  備註  | 
| --- | --- | 
|  S3  |  根據操作輸入，有條件使用 SigV4A 和 SigV4Express。 | 
|  EventBridge  |  根據操作輸入，有條件使用 SigV4A。 | 
|  Cognito  |  某些操作僅限匿名。 | 
|  SSO  |  某些操作僅限匿名。 | 
|  STS  |  某些操作僅限匿名。 | 

# 設定用戶端端點
<a name="configure-endpoints"></a>

**警告**  
 端點解析是進階 SDK 主題。透過變更這些設定，您可能會破壞程式碼。預設設定應適用於生產環境中的大多數使用者。

 適用於 Go 的 AWS SDK 可讓您設定要用於服務的自訂端點。在大多數情況下，預設組態就足夠了。設定自訂端點允許其他行為，例如使用服務的發行前版本。

## 自訂
<a name="customization"></a>

 開發套件中有兩個端點解析組態的「版本」。
+  v2，已於 202Q3發行，透過下列方式設定：
  +  `EndpointResolverV2` 
  +  `BaseEndpoint` 
+  v1，與 SDK 一起發行，透過下列方式設定：
  +  `EndpointResolver` 

 我們建議 v1 端點解析的使用者遷移至 v2，以取得較新的端點相關服務功能的存取權。

## V2：`EndpointResolverV2`\$1 `BaseEndpoint`
<a name="v2-endpointresolverv2--baseendpoint"></a>

 在解析 v2 中， `EndpointResolverV2`是端點解析發生的最終機制。針對您在 SDK 中提出的每個請求，系統會呼叫解析程式`ResolveEndpoint`的方法，做為工作流程的一部分。提出請求時，解析程式`Endpoint`傳回的 主機名稱會**依原樣**使用 （不過，操作序列化程式仍然可以附加到 HTTP 路徑）。

 解決方案 v2 包含額外的用戶端層級組態 `BaseEndpoint`，用於為您的服務執行個體指定 "base" 主機名稱。此處設定的值並非確定性 - 最終會在最終解析發生`EndpointResolverV2`時，以參數形式傳遞給用戶端的 （如需`EndpointResolverV2`參數的詳細資訊，請參閱 )。然後，解析程式實作有機會檢查並可能修改該值，以判斷最終端點。

 例如，如果您使用已指定 的用戶端對指定的儲存貯體執行 S3 `GetObject`請求`BaseEndpoint`，預設解析程式會在與虛擬主機相容 （假設您尚未在用戶端組態中停用虛擬託管） 時，將儲存貯體注入主機名稱。

 實際上， `BaseEndpoint` 最有可能用來將用戶端指向服務的開發或預覽執行個體。

### `EndpointResolverV2` 參數
<a name="endpointresolverv2-parameters"></a>

 每個服務都會接受一組特定的輸入，這些輸入會傳遞至其解析度函數，並在每個服務套件中定義為 `EndpointParameters`。

 每個服務都包含下列基本參數，用於促進 內的一般端點解析 AWS：


|  name  |  type  |  description  | 
| --- | --- | --- | 
|  Region  |  string  |  用戶端 AWS 的區域  | 
|  Endpoint  |  string  |  在用戶端組態BaseEndpoint中為 設定的值  | 
|  UseFips  |  bool  |  是否在用戶端組態中啟用 FIPS 端點  | 
|  UseDualStack  |  bool  |  是否在用戶端組態中啟用雙堆疊端點  | 

 服務可以指定解析所需的其他參數。例如，S3 的 `EndpointParameters`包含儲存貯體名稱，以及數個 S3-specific功能設定，例如是否啟用虛擬主機定址。

 如果您正在實作自己的 `EndpointResolverV2`，則永遠不需要建構自己的 執行個體`EndpointParameters`。開發套件會取得每個請求的值，並將其傳遞給您的實作。

### 有關 Amazon S3 的備註
<a name="a-note-about-amazon-s3"></a>

 Amazon S3 是一種複雜的服務，其許多功能透過複雜的端點自訂建模，例如儲存貯體虛擬託管、S3 MRAP 等。

 因此，建議您不要取代 S3 用戶端中的`EndpointResolverV2`實作。如果您需要擴展其解決行為，也許透過傳送請求到具有其他端點考量的本機開發堆疊，我們建議包裝預設實作，以便將其委派回預設值作為備用 （如以下範例所示）。

### 範例
<a name="examples"></a>

#### 搭配 `BaseEndpoint`
<a name="with-baseendpoint"></a>

 下列程式碼片段顯示如何將 S3 用戶端指向服務的本機執行個體，在此範例中，該執行個體託管在連接埠 8080 的迴路裝置上。

```
client := s3.NewFromConfig(cfg, func (o *svc.Options) {
    o.BaseEndpoint = aws.String("https://localhost:8080/")
})
```

#### 搭配 `EndpointResolverV2`
<a name="with-endpointresolverv2"></a>

 下列程式碼片段說明如何使用 將自訂行為注入 S3 的端點解析`EndpointResolverV2`。

```
import (
    "context"
    "net/url"

    "github.com/aws/aws-sdk-go-v2/service/s3"
    smithyendpoints "github.com/aws/smithy-go/endpoints"
)

type resolverV2 struct {
    // you could inject additional application context here as well
}

func (*resolverV2) ResolveEndpoint(ctx context.Context, params s3.EndpointParameters) (
        smithyendpoints.Endpoint, error,
    ) {
    if /* input params or caller context indicate we must route somewhere */ {
        u, err := url.Parse("https://custom.service.endpoint/")
        if err != nil {
            return smithyendpoints.Endpoint{}, err
        }
        return smithyendpoints.Endpoint{
            URI: *u,
        }, nil
    }

    // delegate back to the default v2 resolver otherwise
    return s3.NewDefaultEndpointResolverV2().ResolveEndpoint(ctx, params)
}

func main() {
    // load config...

    client := s3.NewFromConfig(cfg, func (o *s3.Options) {
        o.EndpointResolverV2 = &resolverV2{
            // ...
        }
    })
}
```

#### 使用兩者
<a name="with-both"></a>

 下列範例程式示範 `BaseEndpoint`和 之間的互動`EndpointResolverV2`。**這是進階使用案例：**

```
import (
    "context"
    "fmt"
    "log"
    "net/url"

    "github.com/aws/aws-sdk-go-v2"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    smithyendpoints "github.com/aws/smithy-go/endpoints"
)

type resolverV2 struct {}

func (*resolverV2) ResolveEndpoint(ctx context.Context, params s3.EndpointParameters) (
        smithyendpoints.Endpoint, error,
    ) {
    // s3.Options.BaseEndpoint is accessible here:
    fmt.Printf("The endpoint provided in config is %s\n", *params.Endpoint)

    // fallback to default
    return s3.NewDefaultEndpointResolverV2().ResolveEndpoint(ctx, params)
}

func main() {
    cfg, err := config.LoadDefaultConfig(context.Background())
    if (err != nil) {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg, func (o *s3.Options) {
        o.BaseEndpoint = aws.String("https://endpoint.dev/")
        o.EndpointResolverV2 = &resolverV2{}
    })

    // ignore the output, this is just for demonstration
    client.ListBuckets(context.Background(), nil)
}
```

 執行時，上述程式會輸出下列項目：

```
The endpoint provided in config is https://endpoint.dev/
```

## V1： `EndpointResolver`
<a name="v1-endpointresolver"></a>

**警告**  
 端點解析 v1 會保留為回溯相容性，並與端點解析 v2 中的現代行為隔離。只有在呼叫者設定 `EndpointResolver` 欄位時，才會使用它。  
 使用 v1 很可能會阻止您存取 v2 解析度發行時或之後推出的端點相關服務功能。如需如何升級的說明，請參閱「遷移」。

 [EndpointResolver](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#EndpointResolver) 可設定為為服務用戶端提供自訂端點解析邏輯。您可以使用自訂端點解析程式，為所有端點或僅特定區域端點覆寫服務的端點解析邏輯。如果自訂解析程式不希望解析請求的端點，自訂端點解析程式可以觸發服務的端點解析邏輯進行備用。[EndpointResolverWithOptionsFunc](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#EndpointResolverWithOptionsFunc) 可用來輕鬆包裝函數以滿足`EndpointResolverWithOptions`界面。

 `EndpointResolver` 您可以透過將包裝有 [WithEndpointResolverWithOptions](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config#WithEndpointResolverWithOptions) 的解析程式傳遞至 [LoadDefaultConfig](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config#LoadDefaultConfig) 來輕鬆設定 ，允許在載入登入資料時覆寫端點，以及`aws.Config`使用自訂端點解析程式設定結果。

 端點解析程式以字串形式提供服務和區域，允許解析程式動態驅動其行為。每個服務用戶端套件都有匯出的`ServiceID`常數，可用來判斷哪個服務用戶端叫用您的端點解析程式。

 端點解析程式可以使用 [EndpointNotFoundError](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#EndpointNotFoundError) sentinel 錯誤值來觸發服務用戶端預設解析邏輯的備用解析。這可讓您選擇無縫覆寫一或多個端點，而無需處理備用邏輯。

 如果您的端點解析程式實作傳回 以外的錯誤`EndpointNotFoundError`，端點解析會停止，而服務操作會傳回錯誤到您的應用程式。

### 範例
<a name="examples-1"></a>

#### 使用備用
<a name="with-fallback"></a>

 下列程式碼片段顯示如何使用其他端點的備用行為，覆寫 DynamoDB 的單一服務端點：

```
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    if service == dynamodb.ServiceID && region == "us-west-2" {
        return aws.Endpoint{
            PartitionID:   "aws",
            URL:           "https://test.us-west-2.amazonaws.com",
            SigningRegion: "us-west-2",
        }, nil
    }
    // returning EndpointNotFoundError will allow the service to fallback to it's default resolution
    return aws.Endpoint{}, &aws.EndpointNotFoundError{}
})

cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithEndpointResolverWithOptions(customResolver))
```

#### 無備用
<a name="without-fallback"></a>

 下列程式碼片段顯示如何覆寫 DynamoDB 的單一服務端點，而沒有其他端點的備用行為：

```
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    if service == dynamodb.ServiceID && region == "us-west-2" {
        return aws.Endpoint{
            PartitionID:   "aws",
            URL:           "https://test.us-west-2.amazonaws.com",
            SigningRegion: "us-west-2",
        }, nil
    }
    return aws.Endpoint{}, fmt.Errorf("unknown endpoint requested")
})

cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithEndpointResolverWithOptions(customResolver))
```

### 不可變端點
<a name="immutable-endpoints"></a>

**警告**  
 將端點設定為不可變可能會阻止某些服務用戶端功能正常運作，並可能導致未定義的行為。將端點定義為不可變時，應小心。

 有些服務用戶端，例如 Amazon S3，可能會修改解析程式針對特定服務操作傳回的端點。例如，Amazon S3 會自動透過變更已解析的端點來處理[虛擬儲存貯體定址](https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html)。您可以將 [HostnameImmutable](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Endpoint.HostnameImmutable) 設定為 ，以防止 SDK 變更您的自訂端點`true`。例如：

```
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    if service == dynamodb.ServiceID && region == "us-west-2" {
        return aws.Endpoint{
            PartitionID:   "aws",
            URL:           "https://test.us-west-2.amazonaws.com",
            SigningRegion: "us-west-2",
            HostnameImmutable: true,
        }, nil
    }
    return aws.Endpoint{}, fmt.Errorf("unknown endpoint requested")
})

cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithEndpointResolverWithOptions(customResolver))
```

## 移轉
<a name="migration"></a>

 從 v1 遷移到 v2 端點解析時，適用下列一般原則：
+  將 [HostnameImmutable](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Endpoint.HostnameImmutable) 設定為 `false` 的[端點](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Endpoint)傳回大約等同於`BaseEndpoint`將 設定為 v1 最初傳回的 URL，並保留`EndpointResolverV2`為預設值。
+  將 HostnameImmutable 設定為 `true` 的端點傳回大約等同於實作 `EndpointResolverV2`，這會傳回 v1 中最初傳回的 URL。
  +  主要例外是針對具有模型化端點字首的操作。這會進一步記下。

 以下提供這些案例的範例。

**警告**  
 V1 不可變端點和 V2 解析度在行為中不相等。例如，S3 Object Lambda 等自訂功能的簽署覆寫仍會針對透過 v1 程式碼傳回的不可變端點進行設定，但 v2 不會進行相同的操作。

### 主機字首注意事項
<a name="note-on-host-prefixes"></a>

 有些操作使用主機字首建模，以附加到已解析的端點。此行為必須與 ResolveEndpointV2 的輸出一起運作，因此主機字首仍會套用至該結果。

 您可以套用中介軟體來手動停用端點主機字首，請參閱範例一節。

### 範例
<a name="examples-2"></a>

#### 可變端點
<a name="mutable-endpoint"></a>

 下列程式碼範例示範如何遷移基本 v1 端點解析程式，以傳回可修改的端點：

```
// v1
client := svc.NewFromConfig(cfg, func (o *svc.Options) {
    o.EndpointResolver = svc.EndpointResolverFromURL("https://custom.endpoint.api/")
})

// v2
client := svc.NewFromConfig(cfg, func (o *svc.Options) {
    // the value of BaseEndpoint is passed to the default EndpointResolverV2
    // implementation, which will handle routing for features such as S3 accelerate,
    // MRAP, etc.
    o.BaseEndpoint = aws.String("https://custom.endpoint.api/")
})
```

#### 不可變端點
<a name="immutable-endpoint"></a>

```
// v1
client := svc.NewFromConfig(cfg, func (o *svc.Options) {
    o.EndpointResolver = svc.EndpointResolverFromURL("https://custom.endpoint.api/", func (e *aws.Endpoint) {
        e.HostnameImmutable = true
    })
})

// v2
import (
    smithyendpoints "github.com/aws/smithy-go/endpoints"
)

type staticResolver struct {}

func (*staticResolver) ResolveEndpoint(ctx context.Context, params svc.EndpointParameters) (
        smithyendpoints.Endpoint, error,
    ) {
    // This value will be used as-is when making the request.
    u, err := url.Parse("https://custom.endpoint.api/")
    if err != nil {
        return smithyendpoints.Endpoint{}, err
    }
    return smithyendpoints.Endpoint{
        URI: *u,
    }, nil
}

client := svc.NewFromConfig(cfg, func (o *svc.Options) {
    o.EndpointResolverV2 = &staticResolver{}
})
```

#### 停用主機字首
<a name="disable-host-prefix"></a>

```
import (
    "context"
    "fmt"
    "net/url"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/<service>"
    smithyendpoints "github.com/aws/smithy-go/endpoints"
    "github.com/aws/smithy-go/middleware"
    smithyhttp "github.com/aws/smithy-go/transport/http"
)

// disableEndpointPrefix applies the flag that will prevent any
// operation-specific host prefix from being applied
type disableEndpointPrefix struct{}

func (disableEndpointPrefix) ID() string { return "disableEndpointPrefix" }

func (disableEndpointPrefix) HandleInitialize(
    ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler,
) (middleware.InitializeOutput, middleware.Metadata, error) {
    ctx = smithyhttp.SetHostnameImmutable(ctx, true)
    return next.HandleInitialize(ctx, in)
}

func addDisableEndpointPrefix(o *<service>.Options) {
    o.APIOptions = append(o.APIOptions, (func(stack *middleware.Stack) error {
        return stack.Initialize.Add(disableEndpointPrefix{}, middleware.After)
    }))
}

type staticResolver struct{}

func (staticResolver) ResolveEndpoint(ctx context.Context, params <service>.EndpointParameters) (
    smithyendpoints.Endpoint, error,
) {
    u, err := url.Parse("https://custom.endpoint.api/")
    if err != nil {
        return smithyendpoints.Endpoint{}, err
    }

    return smithyendpoints.Endpoint{URI: *u}, nil
}


func main() {
    cfg, err := config.LoadDefaultConfig(context.Background())
    if err != nil {
        panic(err)
    }

    svc := <service>.NewFromConfig(cfg, func(o *<service>.Options) {
        o.EndpointResolverV2 = staticResolver{}
    })

    _, err = svc.<Operation>(context.Background(), &<service>.<OperationInput>{ /* ... */ },
        addDisableEndpointPrefix)
    if err != nil {
        panic(err)
    }
}
```

# 自訂 HTTP 用戶端
<a name="configure-http"></a>

 適用於 Go 的 AWS SDK 使用具有預設組態值的預設 HTTP 用戶端。雖然您可以變更其中一些組態值，但在具有高輸送量和低延遲需求的環境中，使用 適用於 Go 的 AWS SDK 的客戶預設 HTTP 用戶端和傳輸並未充分設定。如需詳細資訊，請參閱，[常見問答集](faq-gosdk.md)因為組態建議會因特定工作負載而有所不同。本節說明如何設定自訂 HTTP 用戶端，並使用該用戶端來建立 適用於 Go 的 AWS SDK 呼叫。

 為了協助您建立自訂 HTTP 用戶端，本節說明如何使用 [NewBuildableClient](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/transport/http#NewBuildableClient) 來設定自訂設定，並搭配 適用於 Go 的 AWS SDK 服務用戶端使用該用戶端。

 讓我們定義要自訂的內容。

## 在組態載入期間覆寫
<a name="overriding-during-configuration-loading"></a>

 呼叫 [LoadDefaultConfig](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config#LoadDefaultConfig) 時，可以使用 [WithHTTPClient](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config#WithHTTP) 包裝用戶端並將產生的值傳遞給 ，以提供自訂 HTTP 用戶端`LoadDefaultConfig`。例如，若要以用戶端`customClient`身分傳遞：

```
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithHTTPClient(customClient))
```

## 逾時
<a name="timeout"></a>

 `BuildableHTTPClient` 可以設定請求逾時限制。此逾時包含連線、處理任何重新導向以及讀取完整回應內文的時間。例如，若要修改用戶端逾時：

```
import "github.com/aws/aws-sdk-go-v2/aws/transport/http"

// ...

httpClient := http.NewBuildableClient().WithTimeout(time.Second*5)
```

## 撥號程式
<a name="dialer"></a>

 `BuildableHTTPClient` 提供建置器機制，用於建構具有修改[撥號器](https://golang.org/pkg/net/#Dialer)選項的用戶端。下列範例示範如何設定用戶端`Dialer`設定。

```
import awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http"
import "net"

// ...

httpClient := awshttp.NewBuildableClient().WithDialerOptions(func(d *net.Dialer) {
    d.KeepAlive = -1
    d.Timeout = time.Millisecond*500
})
```

### 設定
<a name="settings"></a>

#### Dialer.KeepAlive
<a name="dialerkeepalive"></a>

 此設定代表作用中網路連線的持續作用期間。

 設定為負值以停用保持連線。

 如果通訊協定和作業系統支援，請將 設為 **0** 以啟用保持連線。

 不支援保持連線的網路通訊協定或作業系統會忽略此欄位。根據預設，TCP 會啟用保持運作。

 請參閱 [https://golang.org/pkg/net/\$1Dialer.KeepAlive](https://golang.org/pkg/net/#Dialer.KeepAlive) 

 `KeepAlive` 設定為 **time.Duration**。

#### Dialer.Timeout
<a name="dialertimeout"></a>

 此設定代表撥號等待建立連線的時間上限。

 預設為 30 秒。

 請參閱 [https://golang.org/pkg/net/\$1Dialer.Timeout](https://golang.org/pkg/net/#Dialer.Timeout) 

 `Timeout` 設定為 **time.Duration**。

## 傳輸
<a name="transport"></a>

 `BuildableHTTPClient` 提供建置器機制，以建構具有修改[傳輸](https://golang.org/pkg/net/http#Transport)選項的用戶端。

### 設定 Proxy
<a name="configuring-a-proxy"></a>

 如果您無法直接連線至網際網路，您可以使用 Go 支援的環境變數 (`HTTP_PROXY`/`HTTPS_PROXY`) 或建立自訂 HTTP 用戶端來設定代理。下列範例會將用戶端設定為使用 `PROXY_URL`做為代理端點：

```
import awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http"
import "net/http"

// ...

httpClient := awshttp.NewBuildableClient().WithTransportOptions(func(tr *http.Transport) {
    proxyURL, err := url.Parse("PROXY_URL")
    if err != nil {
        log.Fatal(err)
    }
    tr.Proxy = http.ProxyURL(proxyURL)
})
```

### 其他設定
<a name="other-settings"></a>

 以下是可以修改以調整 HTTP 用戶端的幾個其他`Transport`設定。您可以在[傳輸](https://golang.org/pkg/net/http/#Transport)類型文件中找到此處未描述的任何其他設定。這些設定可以套用，如下列範例所示：

```
import awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http"
import "net/http"

// ...

httpClient := awshttp.NewBuildableClient().WithTransportOptions(func(tr *http.Transport) {
    tr.ExpectContinueTimeout = 0
    tr.MaxIdleConns = 10
})
```

#### Transport.ExpectContinueTimeout
<a name="transportexpectcontinuetimeout"></a>

 如果請求具有「預期：100-continue」標頭，則此設定代表完整寫入請求標頭後等待伺服器第一個回應標頭的時間上限，此時間不包含傳送請求標頭的時間。HTTP 用戶端會在此逾時結束後傳送其承載。

 預設 1 秒。

 設為 **0** 表示沒有逾時，並在不等待的情況下傳送請求承載。其中一個使用案例是，當您遇到代理或第三方服務的問題時，該問題會採用類似稍後在 函數中使用 Amazon S3 的工作階段。

 請參閱 [https://golang.org/pkg/net/http/\$1Transport.ExpectContinueTimeout](https://golang.org/pkg/net/http/#Transport.ExpectContinueTimeout) 

 `ExpectContinue` 設定為 **time.Duration**。

#### Transport.IdleConnTimeout
<a name="transportidleconntimeout"></a>

 此設定代表 HTTP 請求之間保持閒置網路連線存活的時間上限。

 設為 **0** 表示沒有限制。

 請參閱 [https://golang.org/pkg/net/http/\$1Transport.IdleConnTimeout](https://golang.org/pkg/net/http/#Transport.IdleConnTimeout) 

 `IdleConnTimeout` 設定為 **time.Duration**。

#### Transport.MaxIdleConns
<a name="transportmaxidleconns"></a>

 此設定代表所有主機的閒置 （保持連線） 連線數目上限。提高此值的一個使用案例是當您在短時間內從相同用戶端看到許多連線時 

 **0** 表示沒有限制。

 請參閱 [https://golang.org/pkg/net/http/\$1Transport.MaxIdleConns](https://golang.org/pkg/net/http/#Transport.MaxIdleConns) 

 設定為`MaxIdleConns` **int**。

#### Transport.MaxIdleConnsPerHost
<a name="transportmaxidleconnsperhost"></a>

 此設定代表保持每個主機的閒置 （保持連線） 連線數目上限。提高此值的一個使用案例是當您在短時間內從相同用戶端看到許多連線時 

 預設為每個主機兩個閒置連線。

 設為 **0** 以使用 DefaultMaxIdleConnsPerHost (2)。

 請參閱 [https://golang.org/pkg/net/http/\$1Transport.MaxIdleConnsPerHost](https://golang.org/pkg/net/http/#Transport.MaxIdleConnsPerHost) 

 `MaxIdleConnsPerHost` 設定為 **int**。

#### Transport.ResponseHeaderTimeout
<a name="transportresponseheadertimeout"></a>

 此設定代表等待用戶端讀取回應標頭的時間上限。

 如果用戶端無法在此持續時間內讀取回應的標頭，請求會失敗並出現逾時錯誤。

 使用長時間執行的 Lambda 函數時，請小心設定此值，因為在 Lambda 函數完成或逾時之前，操作不會傳回任何回應標頭。不過，您仍可使用此選項搭配 \$1\$1 InvokeAsync\$1\$1 API 操作。

 預設為不逾時；請等待一段時間。

 請參閱 [https://golang.org/pkg/net/http/\$1Transport.ResponseHeaderTimeout](https://golang.org/pkg/net/http/#Transport.ResponseHeaderTimeout) 

 `ResponseHeaderTimeout` 設定為 **time.Duration**。

#### Transport.TLSHandshakeTimeout
<a name="transporttlshandshaketimeout"></a>

 此設定代表等待 TLS 交握完成的時間上限。

 預設為 10 秒。

 零表示沒有逾時。

 請參閱 [https://golang.org/pkg/net/http/\$1Transport.TLSHandshakeTimeout](https://golang.org/pkg/net/http/#Transport.TLSHandshakeTimeout) 

 `TLSHandshakeTimeout` 設定為 **time.Duration**。

# 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)
```

# 日誌
<a name="configure-logging"></a>

 適用於 Go 的 AWS SDK 有可用的記錄設施，可讓您的應用程式啟用偵錯資訊，以偵錯和診斷請求問題或失敗。[Logger](https://pkg.go.dev/github.com/aws/smithy-go/logging#Logger) 界面和 [ClientLogMode](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#ClientLogMode) 是您可以用來決定用戶端應如何記錄和記錄內容的主要元件。

## Logger
<a name="logger"></a>

 使用 [LoadDefaultConfig](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config#LoadDefaultConfig) 建構 [Config](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Config) 時，預設`Logger`會設定為將日誌訊息傳送至程序的標準錯誤 (stderr)。滿足 [Logger](https://pkg.go.dev/github.com/aws/smithy-go/logging#Logger) 界面的自訂記錄器，可以透過使用 [config.WithLogger](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config#WithLogger) `LoadDefaultConfig`包裝來做為 的引數傳遞至 。

 例如，若要將用戶端設定為使用我們的 `applicationLogger`：

```
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithLogger(applicationLogger))
```

 現在，使用 建構的 設定的用戶端`aws.Config`會將日誌訊息傳送至 `applicationLogger`。

### 內容感知記錄器
<a name="context-aware-loggers"></a>

 Logger 實作可能會實作選用的 [ContextLogger](https://pkg.go.dev/github.com/aws/smithy-go/logging#ContextLogger) 介面。實作此界面的記錄器會使用目前內容叫用其`WithContext`方法。這可讓您的記錄實作傳回新的 `Logger`，根據內容中存在的值來寫入額外的記錄中繼資料。

## ClientLogMode
<a name="clientlogmode"></a>

 根據預設，服務用戶端不會產生日誌訊息。若要設定用戶端傳送日誌訊息以進行偵錯，請在 上使用 [ClientLogMode](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#ClientLogMode) 成員`Config`。 `ClientLogMode` 可設定為啟用偵錯訊息：
+  Signature 第 4 版 (SigV4) 簽署 
+  請求重試 
+  HTTP 請求 
+  HTTP 回應 

 例如，若要啟用 HTTP 請求和重試的記錄：

```
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithClientLogMode(aws.LogRetries | aws.LogRequest))
```

 請參閱 [ClientLogMode](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#ClientLogMode)，了解可用的不同用戶端日誌模式。

# 追蹤和指標
<a name="configure-observability"></a>

 經過 適用於 Go 的 AWS SDK 檢測，可記錄 SDK 操作的追蹤範圍和用戶端指標。根據預設，用戶端會針對追蹤和指標使用無操作實作，這表示除非您設定提供者，否則不會收集任何資料。

 服務用戶端有兩個可觀測性的組態選項：
+  [TracerProvider](https://pkg.go.dev/github.com/aws/smithy-go/tracing#TracerProvider) – 用於建立追蹤器和記錄用戶端追蹤範圍的進入點。
+  [MeterProvider](https://pkg.go.dev/github.com/aws/smithy-go/metrics#MeterProvider) – 用於建立計量和記錄用戶端指標的進入點。

 雖然受到 OpenTelemetry (OTel) 規格的啟發，但這些 APIs會在 中獨立定義`smithy-go`。開發套件提供轉接器模組，可將具體的 OTel 開發套件實作連接到開發套件的提供者界面。

## 追蹤
<a name="configure-tracing"></a>

 使用 [smithyoteltracing](https://pkg.go.dev/github.com/aws/smithy-go/tracing/smithyoteltracing) 轉接器模組將 OTel `trace.TracerProvider`連接至服務用戶端。

 下列範例示範如何設定 Amazon S3 用戶端的追蹤：

```
import (
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/smithy-go/tracing/smithyoteltracing"
    "go.opentelemetry.io/otel/trace"
)

// provider is an OTel trace.TracerProvider that you have configured.
var provider trace.TracerProvider

svc := s3.NewFromConfig(cfg, func(o *s3.Options) {
    o.TracerProvider = smithyoteltracing.Adapt(provider)
})
```

 SDK 操作使用跨階層進行檢測，涵蓋操作生命週期的高階元件，例如請求序列化、簽署和重試迴圈。

## 指標
<a name="configure-metrics"></a>

 使用 [smithyotelmetrics](https://pkg.go.dev/github.com/aws/smithy-go/metrics/smithyotelmetrics) 轉接器模組將 OTel `metric.MeterProvider`連接至服務用戶端。

 下列範例示範如何設定 Amazon S3 用戶端的指標：

```
import (
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/smithy-go/metrics/smithyotelmetrics"
    "go.opentelemetry.io/otel/metric"
)

// provider is an OTel metric.MeterProvider that you have configured.
var provider metric.MeterProvider

svc := s3.NewFromConfig(cfg, func(o *s3.Options) {
    o.MeterProvider = smithyotelmetrics.Adapt(provider)
})
```

### 支援的指標
<a name="supported-metrics"></a>

 SDK 用戶端會收集下列指標：


| 指標名稱 | 單位 | Type | 說明 | 
| --- | --- | --- | --- | 
| client.call.duration | s | 直方圖 | 整體通話持續時間，包括重試次數以及傳送或接收請求和回應內文的時間。 | 
| client.call.attempts | \$1attempt\$1 | MonotonicCounter | 個別操作的嘗試次數。 | 
| client.call.errors | \$1error\$1 | MonotonicCounter | 操作的錯誤數目。 | 
| client.call.attempt\$1duration | s | 直方圖 | 連線到服務、傳送請求，以及取回 HTTP 狀態碼和標頭 （包括排入佇列等待傳送的時間） 的時間。 | 
| client.call.resolve\$1endpoint\$1duration | s | 直方圖 | 為請求解析端點 （端點解析程式，而非 DNS) 的時間。 | 
| client.call.deserialization\$1duration | s | 直方圖 | 還原序列化訊息內文的時間。 | 
| client.call.auth.signing\$1duration | s | 直方圖 | 簽署請求的時間。 | 
| client.call.auth.resolve\$1identity\$1duration | s | 直方圖 | 從身分提供者取得身分 (AWS 憑證、承載字符等） 的時間。 | 

 適用時，每個指標都會包含下列屬性 （維度）：
+ `rpc.service` – 服務名稱。
+ `rpc.method` – 操作名稱。
+ `exception.type` – 錯誤類型 （隨附於 `client.call.errors`)。
+ `auth.scheme_id` – 身分驗證機制 （包含在身分驗證相關指標中）。

### HTTP 用戶端指標
<a name="http-client-metrics"></a>

 軟體開發套件的 HTTP 用戶端會收集與基礎 HTTP 連線生命週期相關的下列其他指標：


| 指標名稱 | 單位 | Type | 說明 | 
| --- | --- | --- | --- | 
| client.http.connections.acquire\$1duration | s | 直方圖 | 請求取得連線所需的時間。 | 
| client.http.connections.dns\$1lookup\$1duration | s | 直方圖 | 執行 DNS 查詢所需的時間。 | 
| client.http.connections.tls\$1handshake\$1duration | s | 直方圖 | 執行 TLS 交握所需的時間。 | 
| client.http.connections.usage | \$1connection\$1 | UpDownCounter | 集區中連線的目前狀態。使用值為 idle或 的state維度acquired。 | 
| client.http.do\$1request\$1duration | s | 直方圖 | 執行 HTTP 請求所花費的總時間。 | 
| client.http.time\$1to\$1first\$1byte | s | 直方圖 | 從傳送請求到接收第一個回應位元組的時間。 | 

# 重試和逾時
<a name="configure-retries-timeouts"></a>

 適用於 Go 的 AWS SDK 可讓您設定 HTTP 服務請求的重試行為。根據預設，服務用戶端會使用 [retry.Standard](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#Standard) 做為其預設的 retryer。如果預設組態或行為不符合您的應用程式需求，您可以調整重試器組態或提供您自己的重試器實作。

 適用於 Go 的 AWS SDK 提供 [aws.Retryer](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Retryer) 界面，可定義要實作的重試實作所需的一組方法。開發套件提供兩種重試實作：[retry.Standard](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#Standard) 和 [aws.NoOpRetryer](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#NoOpRetryer)。

## 標準重試器
<a name="standard-retryer"></a>

 [retry.Standard](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#Standard) retryer 是 SDK 用戶端使用的預設`aws.Retryer`實作。標準重試器是速率有限的重試器，具有可設定的嘗試次數上限，以及調整請求退避政策的功能。

 下表定義此重試器的預設值：


| 屬性 | 預設 | 
| --- | --- | 
|  嘗試次數上限  |  3  | 
|  最大退避延遲  |  20 秒  | 

 當調用您的請求時發生可重試錯誤時，標準重試器將使用其提供的組態來延遲請求，然後重試請求。重試會將 新增至請求的整體延遲，如果預設組態不符合您的應用程式需求，您必須設定重試器。

 如需標準[重試](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry)器實作將哪些錯誤視為可重試的詳細資訊，請參閱重試套件文件。

## NopRetryer
<a name="nopretryer"></a>

 [aws.NopRetryer](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#NopRetryer) 是如果您想要停用所有重試嘗試時所提供的`aws.Retryer`實作。叫用服務用戶端操作時，此重試器只會允許嘗試一次請求，而任何產生的錯誤都會傳回給呼叫應用程式。

## 自訂行為
<a name="customizing-behavior"></a>

 SDK 提供一組協助程式公用程式，可包裝 `aws.Retryer`實作，並傳回以所需重試行為包裝的提供的重試程式。您可以根據您的應用程式需求，覆寫所有用戶端、每個用戶端或每個操作的預設重試器。若要查看顯示如何執行此操作的其他範例，請參閱[重試](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry)套件文件範例。

**警告**  
 如果使用 指定全域`aws.Retryer`實作`config.WithRetryer`，您必須確保傳回`aws.Retryer`每次調用的新執行個體。這將確保您不會在所有服務用戶端之間建立全域重試權杖儲存貯體。

### 限制最大嘗試次數
<a name="limiting-the-max-number-of-attempts"></a>

 您可以使用 [retry.AddWithMaxAttempts](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#AddWithMaxAttempts) 來包裝`aws.Retryer`實作，將最大嘗試次數設定為所需的值。

**警告**  
 使用 `retry.AddWithMaxAttempts`搭配值為零，將允許 SDK 重試所有可重試的錯誤，直到請求成功，或傳回不可重試的錯誤。**允許 SDK 無限重試可能會導致工作負載失控和計費週期膨脹。**

```
import "context"
import "github.com/aws/aws-sdk-go-v2/aws/retry"
import "github.com/aws/aws-sdk-go-v2/config"
import "github.com/aws/aws-sdk-go-v2/service/s3"

// ...

// MaxAttempts will be infinite (will retry indefinitely)
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer {
    return retry.AddWithMaxAttempts(retry.NewStandard(), 0)
}))
if err != nil {
    return err
}

client := s3.NewFromConfig(cfg)
```

 請注意，使用功能選項直接設定 MaxAttempts 來執行個體化重試器的行為會略有不同。更具體地說，設定小於或等於零的值會導致重試器使用預設的嘗試次數上限 3 次，而不是無限次重試：

```
import "context"
import "github.com/aws/aws-sdk-go-v2/aws/retry"
import "github.com/aws/aws-sdk-go-v2/config"
import "github.com/aws/aws-sdk-go-v2/service/s3"

// ...

// MaxAttempts will default to 3
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer {
    return retry.NewStandard(func(o *retry.StandardOptions) {
        o.MaxAttempts = 0
    })
}))
if err != nil {
    return err
}

client := s3.NewFromConfig(cfg)
```

### 限制最大退避延遲
<a name="limiting-the-max-back-off-delay"></a>

 您可以使用 [retry.AddWithMaxBackoffDelay](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#AddWithMaxBackoffDelay) 來包裝`aws.Retryer`實作，並限制重試失敗請求之間允許發生的最大退避延遲。

 例如，您可以下列程式碼，以 5 秒的所需最大延遲包裝標準用戶端重試器：

```
import "context"
import "time"
import "github.com/aws/aws-sdk-go-v2/aws/retry"
import "github.com/aws/aws-sdk-go-v2/config"
import "github.com/aws/aws-sdk-go-v2/service/s3"

// ...

cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer {
    return retry.AddWithMaxBackoffDelay(retry.NewStandard(), time.Second*5)
}))
if err != nil {
    return err
}

client := s3.NewFromConfig(cfg)
```

### 重試其他 API 錯誤代碼
<a name="retry-additional-api-error-codes"></a>

 您可以使用 [retry.AddWithErrorCodes](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#AddWithErrorCodes) 來包裝`aws.Retryer`實作，並包含應視為可重試的其他 API 錯誤代碼。

 例如，您可以下列程式碼來包裝標準用戶端重試器，以包含可重試的 Amazon S3 `NoSuchBucketException`例外狀況。

```
import "context"
import "time"
import "github.com/aws/aws-sdk-go-v2/aws/retry"
import "github.com/aws/aws-sdk-go-v2/config"
import "github.com/aws/aws-sdk-go-v2/service/s3"
import "github.com/aws/aws-sdk-go-v2/service/s3/types"

// ...

cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer {
    return retry.AddWithErrorCodes(retry.NewStandard(), (*types.NoSuchBucketException)(nil).ErrorCode())
}))
if err != nil {
    return err
}

client := s3.NewFromConfig(cfg)
```

### 用戶端速率限制
<a name="client-side-rate-limiting"></a>

 在標準重試政策中 適用於 Go 的 AWS SDK 引入新的用戶端速率限制機制，以符合現代 SDKs的行為。這是由重試器[選項](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#StandardOptions)上的 [RateLimiter](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#RateLimiter) 欄位所控制的行為。

 RateLimiter 會以具有設定容量的字符儲存貯體運作，其中操作嘗試失敗會使用字符。嘗試使用超過可用權杖而導致 [QuotaExceededError](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/ratelimit#QuotaExceededError) 操作失敗的重試。

 預設實作的參數化方式如下 （如何修改每個設定）：
+  容量為 500 （使用 NewTokenRateLimit 在 StandardOptions 上設定 RateLimiter 的值） [NewTokenRateLimit](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/ratelimit#NewTokenRateLimit) 
+  逾時成本 10 個字符所造成的重試 （在 StandardOptions 上設定 RetryTimeoutCost) 
+  其他錯誤導致的重試需要 5 個字符 （在 StandardOptions 上設定 RetryCost) 
+  在第一次嘗試時成功的 操作會新增 1 個字符 （在 StandardOptions 上設定 NoRetryIncrement) 
  +  第 2 次或之後嘗試成功的操作不會新增任何字符 

 如果您發現預設行為不符合應用程式的需求，您可以使用 [ratelimit.None](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/ratelimit#pkg-variables) 將其停用。

#### 範例：修改速率限制器
<a name="example-modified-rate-limiter"></a>

```
import (
    "context"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/aws/ratelimit"
    "github.com/aws/aws-sdk-go-v2/aws/retry"
    "github.com/aws/aws-sdk-go-v2/config"
)

// ...

cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRetryer(func() aws.Retryer {
    return retry.NewStandard(func(o *retry.StandardOptions) {
        // Makes the rate limiter more permissive in general. These values are
        // arbitrary for demonstration and may not suit your specific
        // application's needs.
        o.RateLimiter = ratelimit.NewTokenRateLimit(1000)
        o.RetryCost = 1
        o.RetryTimeoutCost = 3
        o.NoRetryIncrement = 10
    })
}))
```

#### 範例：沒有使用 ratelimit.None 的速率限制
<a name="example-no-rate-limit-using-ratelimitnone"></a>

```
import (
    "context"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/aws/ratelimit"
    "github.com/aws/aws-sdk-go-v2/aws/retry"
    "github.com/aws/aws-sdk-go-v2/config"
)

// ...

cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRetryer(func() aws.Retryer {
    return retry.NewStandard(func(o *retry.StandardOptions) {
        o.RateLimiter = ratelimit.None
    })
}))
```

## 逾時
<a name="timeouts"></a>

 叫用服務用戶端操作時，您可以使用[內容](https://golang.org/pkg/context/)套件來設定逾時或截止日期。使用 [內容。WithDeadline](https://golang.org/pkg/context/#WithDeadline) 可包裝您的應用程式內容，並將截止日期設定為必須完成調用操作的特定時間。在特定`time.Duration`使用[內容之後設定逾時。WithTimeout](https://golang.org/pkg/context/#WithTimeout)。軟體開發套件會在叫用服務 API 時，將提供的 傳遞`context.Context`給 HTTP 傳輸用戶端。如果在叫用 操作時，傳遞到軟體開發套件的內容已取消或變成取消，軟體開發套件將不會進一步重試請求，並會返回呼叫應用程式。如果提供給 SDK 的內容遭到取消，您必須在應用程式中適當地處理內容取消。

### 設定逾時
<a name="setting-a-timeout"></a>

 下列範例示範如何設定服務用戶端操作的逾時。

```
import "context"
import "time"

// ...

ctx := context.TODO() // or appropriate context.Context value for your application

client := s3.NewFromConfig(cfg)

// create a new context from the previous ctx with a timeout, e.g. 5 seconds
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()

resp, err := client.GetObject(ctx, &s3.GetObjectInput{
    // input parameters
})
if err != nil {
    // handle error
}
```