

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# SDK 구성
<a name="configure-gosdk"></a>

 AWS SDK for Go V2에서는 로거, 로그 수준 및 재시도 구성과 같은 서비스 클라이언트에 대한 공통 설정을 구성할 수 있습니다. 대부분의 설정은 선택 사항입니다. 그러나 각 서비스 클라이언트에 대해 AWS 리전과 자격 증명을 지정해야 합니다. SDK는 이러한 값을 사용하여 올바른 리전으로 요청을 보내고 올바른 자격 증명으로 요청에 서명합니다. 이러한 값은 코드 또는 실행 환경을 통해 프로그래밍 방식으로 지정할 수 있습니다.

## AWS 공유 구성 파일 로드
<a name="loading-aws-shared-configuration"></a>

 서비스 API 클라이언트를 초기화하는 방법에는 여러 가지가 있지만 사용자에게 권장되는 가장 일반적인 패턴은 다음과 같습니다.

 AWS 공유 구성 파일을 사용하도록 SDK를 구성하려면 다음 코드를 사용합니다.

```
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 공유 구성 파일에 대한 자세한 내용은 SDK 및 도구 참조 안내서의 [ 구성을](https://docs.aws.amazon.com/sdkref/latest/guide/creds-config-files.html) 참조하세요. AWS SDKs 

## AWS 리전 지정
<a name="specifying-the-aws-region"></a>

 리전을 지정할 때 `us-west-2` 또는 `us-east-2`와 같은 요청을 보낼 위치를 지정합니다. 각 서비스의 리전 목록을 보려면, Amazon Web Services 일반 참조의 [서비스 엔드포인트 및 할당량](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html)을 참조하세요.

 SDK에는 기본 리전이 없습니다. 리전을 지정하려면 다음을 수행합니다.
+  기본 리전에 `AWS_REGION` 환경 변수를 설정합니다.
+  구성을 로드할 때 `config.LoadDefaultConfig`에 [config.WithRegion](https://github.com/aws/aws-sdk-go-v2/blob/config/v0.2.2/config/provider.go#L127)을 인수로 사용하여 리전을 명시적으로 설정합니다.

 검토: 이러한 모든 기술을 사용하여 리전을 설정하는 경우 SDK는 명시적으로 지정한 리전을 사용합니다.

### 환경 변수를 사용하여 리전 구성
<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>

 에는 요청에 서명하기 위한 자격 증명(액세스 키 및 보안 액세스 키)이 AWS SDK for Go 필요합니다 AWS. 특정 사용 사례에 따라 여러 위치에서 자격 증명을 지정할 수 있습니다. 자격 증명을 받는 방법에 대한 자세한 내용은 [AWS SDK for Go 시작하기](getting-started.md) 섹션을 참조하세요.

 를 사용하여 `aws.Config` 인스턴스를 초기화하면 SDK`config.LoadDefaultConfig`는 기본 자격 증명 체인을 사용하여 AWS 자격 증명을 찾습니다. 이 기본 자격 증명 체인은 다음 순서대로 자격 증명을 찾습니다.

1.  환경 변수.

   1.  정적 자격 증명(`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_SESSION_TOKEN`) 

   1.  웹 자격 증명 토큰(`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는 수동 구성 없이 기본 제공 공급자를 자동으로 감지하고 사용합니다. 예를 들어 Amazon EC2 인스턴스에 IAM 역할을 사용하는 경우 애플리케이션은 인스턴스의 자격 증명을 자동으로 사용합니다. 애플리케이션에서 자격 증명을 수동으로 구성할 필요가 없습니다.

 가장 좋은 방법은 자격 증명을 다음 순서로 AWS 지정하는 것입니다.

1.  애플리케이션이 Amazon ECS 태스크 정의 또는 RunTask API 작업을 사용하는 경우 태스크에 IAM 역할을 사용합니다.

1.  애플리케이션이 Amazon EC2 인스턴스에서 실행 중인 경우 Amazon EC2에 IAM 역할을 사용합니다.

    IAM 역할은 인스턴스의 애플리케이션을 임시 보안 자격 증명으로 제공하여 AWS 호출합니다. IAM 역할은 여러 Amazon EC2 인스턴스에서 보안 인증을 배포 및 관리할 수 있는 쉬운 방법을 제공합니다.

1.  공유 자격 증명 또는 구성 파일을 사용합니다.

    자격 증명 및 구성 파일은 다른 AWS SDK 및 AWS CLI에서 공유됩니다. 보안 모범 사례로 액세스 키 ID 및 보안 키와 같은 민감한 값을 설정하려면 자격 증명 파일을 사용하는 것이 좋습니다. 다음은 이러한 각 파일의 [형식 지정 요구 사항](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 역할을 사용하도록 인스턴스를 구성한 경우 SDK는 애플리케이션에 이러한 자격 증명을 자동으로 사용합니다. 이러한 자격 증명을 수동으로 지정할 필요가 없습니다.

### 공유 자격 증명 및 구성
<a name="shared-credentials-and-configuration"></a>

 공유 자격 증명 및 구성 파일을 사용하여 AWS SDKs 및 기타 도구 간에 공통 구성을 공유할 수 있습니다. 다양한 도구나 애플리케이션에 대해 서로 다른 자격 증명을 사용하는 경우 *프로파일*을 사용하여 동일한 구성 파일에서 여러 액세스 키를 구성할 수 있습니다.

 `config.LoadOptions`를 사용하여 여러 자격 증명 또는 구성 파일 위치를 제공할 수 있습니다. 기본적으로 SDK는 [자격 증명 지정](#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.  프로필이 자격 증명 파일과 구성 파일 모두에 있는 경우 자격 증명 파일 속성이 우선합니다.

 필요한 경우 `config.LoadOptions`에서 `LogConfigurationWarnings`를 활성화하고 프로필 확인 단계를 기록할 수 있습니다.

#### 자격 증명 파일 생성
<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]` 제목은 다른 프로필을 사용하도록 구성하지 않는 한 SDK가 사용할 기본 프로필의 자격 증명을 정의합니다.

 다음 예제와 같이 프로필에 세션 토큰을 추가하여 임시 보안 자격 증명을 사용할 수도 있습니다.

```
[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 SDK 및 도구 참조 안내서](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html#file-format-creds)에서 자세한 내용을 읽을 수 있습니다.

#### 구성 파일 생성
<a name="creating-the-config-file"></a>

 공유 자격 증명 파일(`.aws/config`)이 없는 경우 텍스트 편집기를 사용하여 홈 디렉터리에 파일을 생성할 수 있습니다. 구성 파일에 다음 콘텐츠를 추가하여 *<REGION>*을 원하는 리전으로 바꿉니다.

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

 `[default]` 제목은 다른 프로필을 사용하도록 구성하지 않는 한 SDK가 사용할 기본 프로필의 구성을 정의합니다.

 다음 예시와 같이 이름이 지정된 프로필을 사용할 수 있습니다.

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

 구성 파일 내의 기본이 아닌 프로필의 섹션 이름은 항상 단어 `profile`로 시작하고 의도한 프로필 이름을 따라야 합니다. [AWS SDK 및 도구 참조 안내서](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>
```

 기본적으로 SDK는 `AWS_PROFILE` 환경 변수를 확인하여 사용할 프로필을 결정합니다. `AWS_PROFILE` 변수가 설정되지 않은 경우 SDK는 `default` 프로필을 사용합니다.

 경우에 따라 애플리케이션에 다른 프로필을 사용할 수 있습니다. 예를 들어 `myapp` 애플리케이션에 `test-account` 자격 증명을 사용하려고 합니다. 다음 명령을 사용하여 이 프로필을 사용할 수 있습니다.

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

 `config.LoadDefaultConfig`를 직접 호출하기 전에 `os.Setenv("AWS_PROFILE", "test-account")`를 직접 호출하거나 다음 예제와 같이 명시적 프로필을 인수로 전달하여 SDK에 프로필을 선택하도록 지시할 수도 있습니다.

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

**참고**  
환경 변수에서 자격 증명을 지정하는 경우 SDK는 지정한 프로필에 관계없이 항상 해당 자격 증명을 사용합니다.

### 환경 변수
<a name="environment-variables"></a>

 기본적으로 SDK는 사용자 환경에서 설정된 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))
```

 이 예제와 같이 자격 증명을 명시적으로 제공하는 경우 SDK는 해당 자격 증명만 사용합니다.

**참고**  
`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>

 [credentials.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")),
)
```

**주의**  
 애플리케이션 내에 자격 증명을 포함하지 마세요. 이 메서드는 테스트 목적으로만 사용하세요.

#### Single Sign-On 자격 증명
<a name="single-sign-on-credentials"></a>

 SDK는를 사용하여 임시 자격 증명을 검색하기 위한 AWS 자격 증명 공급자를 제공합니다 AWS IAM Identity Center. 를 사용하여 AWS 액세스 포털로 AWS CLI인증하고 임시 AWS 자격 증명에 대한 액세스를 승인합니다. 그런 다음 Single Sign-On(SSO) 프로파일을 로드하도록 애플리케이션을 구성하고 SDK는 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 IAM Identity Center](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html) AWS CLI 참조하세요 AWS CLI . SSO 자격 증명 공급자를 프로그래밍 방식으로 구성하는 방법에 대한 자세한 내용은 [ssocreds](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials/ssocreds) API 참조 설명서를 참조하세요.

#### 로그인 자격 증명
<a name="login-credentials"></a>

기존 AWS Management Console 로그인 자격 증명을 사용하여 AWS 서비스에 프로그래밍 방식으로 액세스할 수 있습니다. 브라우저 기반 인증 흐름 후는 AWS CLI 및 AWS SDKs AWS Tools for PowerShell 와 같은 로컬 개발 도구에서 작동하는 임시 자격 증명을 AWS 생성합니다. 이 기능은 특히 장기 액세스 키를 관리하는 것보다 대화형 인증을 선호하는 경우 AWS CLI 자격 증명을 구성하고 관리하는 프로세스를 간소화합니다.

1.  AWS CLI를 사용하여 로그인 흐름을 시작하고 브라우저 프롬프트를 따릅니다. 이 예제에서는 로그인 세션을 새 프로필에 저장**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) - 호스트 환경의 쉘에서 간접적으로 호출할 외부 프로세스에서 자격 증명을 검색합니다.
+  [stscreds](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials/stscreds) -에서 자격 증명 검색 AWS STS 

# 인증 구성
<a name="configure-auth"></a>

 AWS SDK for Go는 인증 동작 서비스를 구성하는 기능을 제공합니다. 대부분의 경우 기본 구성으로도 충분하지만 사용자 지정 인증을 구성하면 시험판 서비스 기능 작업과 같은 추가 동작을 수행할 수 있습니다.

## 정의
<a name="definitions"></a>

 이 섹션에서는 AWS SDK for Go의 인증 구성 요소에 대한 개략적인 설명을 제공합니다.

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

 [AuthScheme](https://pkg.go.dev/github.com/aws/smithy-go/transport/http#AuthScheme)은 SDK가 호출자 자격 증명을 검색하여 작업 요청에 연결하는 워크플로를 정의하는 인터페이스입니다.

 인증 체계는 아래에 자세히 설명된 다음 구성 요소를 사용합니다.
+  체계를 식별하는 고유 ID 
+  서명 프로세스에 사용되는 호출자 자격 증명(예: AWS 자격 증명)을 반환하는 자격 증명 해석기 
+  작업의 전송 요청에 호출자 자격 증명을 실제로 삽입하는 서명자(예: `Authorization` HTTP 헤더) 

 각 서비스 클라이언트 옵션에는 `AuthSchemes` 필드가 포함되며, 기본적으로 이 필드는 해당 서비스에서 지원하는 인증 체계 목록으로 채워집니다.

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

 각 서비스 클라이언트 옵션에는 `AuthSchemeResolver` 필드가 포함됩니다. 서비스별로 정의된 이 인터페이스는 각 작업에 대해 가능한 인증 옵션을 결정하기 위해 SDK에서 호출하는 API입니다.

**중요**  
 인증 체계 해석기는 사용되는 인증 체계를 지정하지 않습니다. 사용할 *수 있는* 체계 목록('옵션')을 반환하고 [여기](#auth-scheme-resolution-workflow)에 설명된 고정 알고리즘을 통해 최종 체계를 선택합니다.

### 옵션
<a name="option"></a>

 `ResolverAuthSchemes`에 대한 직접 호출에서 반환되는 [옵션](https://pkg.go.dev/github.com/aws/smithy-go/auth#Option)은 가능한 인증 옵션을 나타냅니다.

 옵션은 세 가지 정보 세트로 구성됩니다.
+  가능한 체계를 나타내는 ID 
+  체계의 자격 증명 해석기에 제공할 불투명한 속성 세트 
+  체계의 서명자에 제공할 불투명한 속성 세트 

#### 속성에 대한 참고 사항
<a name="a-note-on-properties"></a>

 사용 사례의 99%에서 호출자는 자격 증명 확인 및 서명을 위한 불투명한 속성에 대해 걱정할 필요가 없습니다. SDK는 각 체계에 필요한 속성을 가져와 SDK에 노출된 강력한 유형의 인터페이스에 전달합니다. 예를 들어 서비스의 기본 인증 해석기는 서명 이름 및 리전에 대한 서명자 속성을 갖도록 SigV4 옵션을 인코딩합니다. 서명 이름 및 리전의 값은 SigV4를 선택할 때 클라이언트의 구성된 [v4.HTTPSigner](https://pkg.go.dev/github.com/aws/smithy-go/auth#Option) 구현으로 전달됩니다.

### 자격 증명
<a name="identity"></a>

 [자격 증명](https://pkg.go.dev/github.com/aws/smithy-go/auth#Identity)은 SDK 호출자를 추상적으로 표현한 것입니다.

 SDK에 사용되는 가장 일반적인 유형의 자격 증명은 `aws.Credentials` 집합입니다. 대부분의 사용 사례에서 호출자는 `Identity`를 추상화로 간주할 필요가 없으며 구체적인 유형으로 직접 작업할 수 있습니다.

**참고**  
 이전 버전과의 호환성을 유지하고 API 혼동을 방지하기 위해 AWS SDK별 자격 증명 유형 `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))으로 SDK에 존재하며, SDK는 이 매핑을 내부적으로 처리합니다.

 호출자는 외부 인증 체계를 정의할 때 `IdentityResolver` 인터페이스를 직접 구현하기만 하면 됩니다.

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

 [서명자](https://pkg.go.dev/github.com/aws/smithy-go/transport/http#Signer)는 검색된 호출자 `Identity`로 요청이 보완되는 인터페이스입니다.

 `Signer`의 구체적인 버전은 강력한 형식(예: [v4.HTTPSigner](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/signer/v4#HTTPSigner))으로 SDK에 존재하며, SDK는 이 매핑을 내부적으로 처리합니다.

 호출자는 외부 인증 체계를 정의할 때 `Signer` 인터페이스를 직접 구현하기만 하면 됩니다.

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

 각 서비스는 각 서비스 패키지에 `AuthResolverParameters`로 정의된 확인 함수로 전달되는 특정 입력 세트를 가져옵니다.

 기본 해석기 파라미터는 다음과 같습니다.


|  name  |  유형  |  설명  | 
| --- | --- | --- | 
|  Operation  |  string  |  간접적으로 호출 중인 작업의 이름입니다. | 
|  Region  |  string  |  클라이언트의 AWS 리전입니다. SigV4[A]를 사용하는 서비스에만 표시됩니다. | 

 자체 해석기를 구현하는 경우 파라미터의 자체 인스턴스를 구성할 필요가 없습니다. SDK는 요청당 이러한 값을 소싱하여 구현에 전달합니다.

## 인증 체계 해결 워크플로
<a name="auth-scheme-resolution-workflow"></a>

 SDK를 통해 AWS 서비스 작업을 직접 호출하면 요청이 직렬화된 후 다음과 같은 일련의 작업이 수행됩니다.

1.  SDK는 필요에 따라 입력 파라미터를 소싱하여 클라이언트의 `AuthSchemeResolver.ResolveAuthSchemes()` API를 직접 호출하여 작업에 사용할 수 있는 [옵션](https://pkg.go.dev/github.com/aws/smithy-go/auth#Option) 목록을 가져옵니다.

1.  SDK는 해당 목록을 반복하고 다음 조건을 충족하는 첫 번째 체계를 선택합니다.
   +  ID가 일치하는 체계가 클라이언트 자체 `AuthSchemes` 목록에 있습니다.
   +  체계의 자격 증명 해석기가 클라이언트의 옵션에 있음(비`nil`)(체계의 `GetIdentityResolver` 메서드를 통해 확인됨, 위에서 설명한 구체적인 자격 증명 해석기 유형에 대한 매핑은 내부적으로 처리됨)(1) 

1.  실행 가능한 체계가 선택되었다고 가정하면 SDK는 `GetIdentityResolver()` API를 간접적으로 호출하여 호출자의 자격 증명을 검색합니다. 예를 들어 내장 SigV4 인증 체계는 내부적으로 클라이언트의 `Credentials` 공급자에 매핑됩니다.

1.  SDK는 자격 증명 해석기의 `GetIdentity()`를 호출합니다(예: SigV4용 `aws.CredentialProvider.Retrieve()`).

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>

 다음 인증 체계는 기본적으로 AWS SDK for Go에서 지원됩니다.


|  명칭  |  체계 ID  |  자격 증명 해석기  |  Signer  |  Notes  | 
| --- | --- | --- | --- | --- | 
|  [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  |  해당 사항 없음  |  SigV4A 사용은 현재 제한되어 있으며 서명자 구현은 내부적입니다. HTTP 요청에 서명하기 위한 범용 API를 제공하는 새로운 옵트인 모듈 aws-http-auth에 대한 이 [공지](https://github.com/aws/aws-sdk-go-v2/discussions/2812)를 참조하세요. | 
|  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  |  해당 사항 없음  |  해당 사항 없음  |  인증 없음 - 자격 증명이 필요하지 않으며 요청에 서명되거나 인증되지 않습니다. | 

### 자격 증명 구성
<a name="identity-configuration"></a>

 AWS SDK for Go에서 인증 체계의 자격 증명 구성 요소는 SDK 클라이언트 `Options`에서 구성됩니다. SDK는 작업이 호출될 때 선택한 체계에 대해 이러한 구성 요소의 값을 자동으로 선택하고 사용합니다.

**참고**  
 이전 버전과의 호환성을 위해 SDK는 자격 증명 해석기가 구성되지 않은 경우 익명 인증 체계의 사용을 암시적으로 허용합니다. 이는 클라이언트의 `Options`의 모든 자격 증명 해석기를 `nil`로 설정하여 수동으로 수행할 수 있습니다(sigv4 자격 증명 해석기는 `aws.AnonymousCredentials{}`로 설정할 수도 있음).

### 서명자 구성
<a name="signer-configuration"></a>

 AWS SDK for Go에서 인증 체계의 서명자 구성 요소는 SDK 클라이언트 `Options`에서 구성됩니다. SDK는 작업이 호출될 때 선택한 체계에 대해 이러한 구성 요소의 값을 자동으로 선택하고 사용합니다. 추가 구성은 필요하지 않습니다.

#### 사용자 지정 인증 체계
<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`를 계측하여 체계의 ID로 인증 `Option`을 반환합니다.

**주의**  
 다음 서비스에는 고유하거나 사용자 지정된 인증 동작이 있습니다. 사용자 지정 인증 동작이 필요한 경우 기본 구현에 위임하고 그에 따라 래핑하는 것이 좋습니다.  


|  Service  |  Notes  | 
| --- | --- | 
|  S3  |  작업 입력에 따라 SigV4A 및 SigV4Express의 조건부 사용. | 
|  EventBridge  |  작업 입력에 따라 SigV4A의 조건부 사용. | 
|  Cognito  |  특정 작업은 익명 전용입니다. | 
|  SSO  |  특정 작업은 익명 전용입니다. | 
|  STS  |  특정 작업은 익명 전용입니다. | 

# 클라이언트 엔드포인트 구성
<a name="configure-endpoints"></a>

**주의**  
 엔드포인트 확인은 고급 SDK 주제입니다. 이러한 설정을 변경하면 코드가 손상될 위험이 있습니다. 기본 설정은 프로덕션 환경 내 대부분의 사용자에게 적용 가능해야 합니다.

 는 서비스에 사용할 사용자 지정 엔드포인트를 구성하는 기능을 AWS SDK for Go 제공합니다. 대부분의 경우는 기본 구성으로도 충분합니다. 사용자 지정 엔드포인트를 구성하면 서비스의 프리릴리스 버전 작업과 같은 추가 동작을 수행할 수 있습니다.

## 사용자 지정
<a name="customization"></a>

 SDK 내에는 엔드포인트 확인 구성의 두 가지 ‘버전’이 있습니다.
+  2023년 Q3에 릴리스되었으며 다음을 통해 구성된 v2: 
  +  `EndpointResolverV2` 
  +  `BaseEndpoint` 
+  SDK와 함께 릴리스되었으며 다음을 통해 구성된 v1: 
  +  `EndpointResolver` 

 v1 엔드포인트 확인을 사용 중인 경우, 최신 엔드포인트 관련 서비스 기능에 액세스하려면 v2로 마이그레이션하는 것이 좋습니다.

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

 확인 v2에서 `EndpointResolverV2`는 엔드포인트 확인이 발생하는 최종 메커니즘입니다. 해석기의 `ResolveEndpoint` 메서드는 SDK에서 수행하는 모든 요청에서 워크플로의 일부로 간접 호출됩니다. 해석기가 반환한 `Endpoint`의 호스트 이름은 요청 시 **그대로** 사용됩니다(단, 작업 직렬화기는 여전히 HTTP 경로에 추가할 수 있음).

 확인 v2에는 서비스 인스턴스의 ‘기본’ 호스트 이름을 지정하는 데 사용되는 추가 클라이언트 수준 구성인 `BaseEndpoint`가 포함되어 있습니다. 여기에 설정된 값은 확정적이지 않습니다. 최종 확인이 발생하면 궁극적으로 클라이언트의 `EndpointResolverV2`에 파라미터로 전달됩니다(`EndpointResolverV2` 파라미터에 대한 자세한 내용 참조). 그러면 해석기 구현을 통해 해당 값을 검사하고 잠재적으로 수정하여 최종 엔드포인트를 결정할 수 있습니다.

 예를 들어 `BaseEndpoint`를 지정한 클라이언트를 사용하여 주어진 버킷에 대해 S3 `GetObject` 요청을 수행하는 경우, 가상 호스트와 호환되면(클라이언트 구성에서 가상 호스팅을 비활성화하지 않은 경우) 기본 해석기가 버킷을 호스트 이름에 주입합니다.

 실제로 `BaseEndpoint`는 클라이언트가 서비스의 개발 또는 미리 보기 인스턴스를 가리키는 데 사용될 가능성이 높습니다.

### `EndpointResolverV2` 파라미터
<a name="endpointresolverv2-parameters"></a>

 각 서비스는 각 서비스 패키지에 `EndpointParameters`로 정의된 확인 함수로 전달되는 특정 입력 세트를 가져옵니다.

 모든 서비스에는 AWS내에서 일반적인 엔드포인트 확인을 용이하게 하는 데 사용되는 다음의 기본 파라미터가 포함되어 있습니다.


|  이름  |  type  |  description  | 
| --- | --- | --- | 
|  Region  |  string  |  클라이언트의 AWS 리전  | 
|  Endpoint  |  string  |  클라이언트 구성에서 BaseEndpoint에 대해 설정된 값  | 
|  UseFips  |  bool  |  클라이언트 구성에서 FIPS 엔드포인트가 활성화되었는지 여부  | 
|  UseDualStack  |  bool  |  클라이언트 구성에서 듀얼 스택 엔드포인트가 활성화되었는지 여부  | 

 서비스는 해결에 필요한 추가 파라미터를 지정할 수 있습니다. 예를 들어 S3의 `EndpointParameters`에는 버킷 이름 외에도 가상 호스트 주소 지정 활성화 여부와 같은 여러 S3 전용 기능 설정이 포함됩니다.

 자체 `EndpointResolverV2`를 구현하는 경우 자체 `EndpointParameters` 인스턴스를 구성할 필요가 없습니다. SDK는 요청당 값을 소싱하여 구현에 전달합니다.

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

 다음 코드 조각은 `EndpointResolverV2`를 사용하여 S3의 엔드포인트 확인에 사용자 지정 동작을 주입하는 방법을 보여줍니다.

```
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` 인터페이스를 충족하는 데 필요한 함수를 쉽게 래핑할 수 있습니다.

 [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)에 전달하여 `EndpointResolver`를 쉽게 구성할 수 있으므로 자격 증명을 로드할 때 엔드포인트를 재정의하고 사용자 지정 엔드포인트 해석기로 결과 `aws.Config`를 구성할 수 있습니다.

 엔드포인트 해석기에는 서비스와 리전이 문자열로 제공되므로 해석기가 동적으로 동작을 구동할 수 있습니다. 각 서비스 클라이언트 패키지에는 엔드포인트 해석기를 간접적으로 호출하는 서비스 클라이언트를 결정하는 데 사용할 수 있는 내보낸 `ServiceID` 상수가 있습니다.

 엔드포인트 해석기는 [EndpointNotFoundError](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#EndpointNotFoundError) 감시 오류 값을 사용하여 서비스 클라이언트 기본 해결 로직에 대한 폴백 확인을 트리거할 수 있습니다. 이렇게 하면 폴백 로직을 처리할 필요 없이 하나 이상의 엔드포인트를 원활하게 선택적으로 재정의할 수 있습니다.

 엔드포인트 해석기 구현에서 `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)을 `true`로 설정하여 SDK가 사용자 지정 엔드포인트를 변경하지 못하도록 할 수 있습니다. 예제: 

```
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`로 설정된 엔드포인트를 반환하는 것은 v1에서 원래 반환된 URL을 반환하는 `EndpointResolverV2`를 구현하는 것과 거의 동일합니다.
  +  기본 예외는 모델링된 엔드포인트 접두사가 있는 작업을 위한 것입니다. 이에 대한 자세한 내용은 아래에 나와 있습니다.

 이러한 사례에 대한 예제는 아래에 제시되어 있습니다.

**주의**  
 V1 변경 불가능 엔드포인트와 V2 확인은 동작이 동일하지 않습니다. 예를 들어 S3 객체 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>

 AWS SDK for Go는 기본 구성 값과 함께 기본 HTTP 클라이언트를 사용합니다. 이러한 구성 값 중 일부를 변경할 수 있지만 기본 HTTP 클라이언트 및 전송은 처리량이 높고 지연 시간이 짧은 환경에서 AWS SDK for Go를 사용하는 고객을 위해 충분히 구성되지 않습니다. 구성 권장 사항은 특정 워크로드에 따라 다르므로 자세한 내용은 [FAQ](faq-gosdk.md) 섹션을 참조하세요. 이 섹션에서는 사용자 지정 HTTP 클라이언트를 구성하고 해당 클라이언트를 사용하여 AWS SDK for Go 직접 호출을 생성하는 방법을 설명합니다.

 사용자 지정 HTTP 클라이언트를 생성하는 데 도움이 되도록 이 섹션에서는 [NewBuildableClient](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/transport/http#NewBuildableClient)가 사용자 지정 설정을 구성하고 해당 클라이언트를 AWS SDK for Go 서비스 클라이언트와 함께 사용하는 방법을 설명합니다.

 사용자 지정하려는 항목을 정의해 보겠습니다.

## 구성 로드 중 재정의
<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)를 사용하여 클라이언트를 래핑하고 결과 값을 `LoadDefaultConfig`에 전달하여 사용자 지정 HTTP 클라이언트를 제공할 수 있습니다. 예를 들어 `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) 옵션으로 클라이언트를 구성하기 위한 빌더 메커니즘을 제공합니다.

### 프록시 구성
<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>

 요청에 "Expect: 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>

 이 설정은 모든 호스트에서 유휴(keep-alive) 연결의 최대 수를 나타냅니다. 이 값을 늘리는 한 가지 사용 사례는 동일한 클라이언트에서 단기간에 많은 연결이 표시되는 경우입니다.

 **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>

 이 설정은 호스트당 유지할 유휴(keep-alive) 연결의 최대 수를 나타냅니다. 이 값을 늘리는 한 가지 사용 사례는 동일한 클라이언트에서 단기간에 많은 연결이 표시되는 경우입니다.

 기본값은 호스트당 두 개의 유휴 연결입니다.

 DefaultMaxIdleConnsPerHost를 사용하려면 **0**으로 설정합니다. (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초입니다.

 0은 제한 시간이 없음을 의미합니다.

 [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>

 AWS SDK for Go v2는 요청 처리를 사용자 지정하기 위한 인터셉터와 미들웨어를 모두 제공합니다. 둘 다 목적이 비슷하지만 다양한 대상과 사용 사례에 맞게 설계되었습니다.
+  **인터셉터**는 간단한 HTTP 중심 API를 사용하여 요청/응답 처리를 사용자 지정하려는 SDK 사용자를 위해 설계되었습니다. 요청 수명 주기에서 특정 후크 포인트를 제공하고 HTTP 요청 및 응답과 직접 작동합니다.
+  **미들웨어**는 전송에 구애받지 않는 고급 시스템으로, 주로 SDK에서 내부적으로 사용됩니다. 미들웨어는 강력하지만 SDK 내부 기능에 대한 심층적인 지식이 요구되며 더 복잡한 인터페이스가 필요합니다.

 일반적인 사용 사례에서 미들웨어 대비 인터셉터의 주요 이점은 다음과 같습니다.
+  **HTTP 중심**: 인터셉터는 HTTP 요청 및 응답에서 직접 작동하므로 미들웨어에 필요한 전송 유형을 확인할 필요가 없습니다.
+  **더 간단한 인터페이스**: 각 인터셉터 후크에는 일반 미들웨어 패턴이 아닌 특정 집중 인터페이스가 있습니다.
+  **더 명확한 실행 모델**: 인터셉터는 미들웨어 스택 주문에 대한 지식 없이 요청 수명 주기의 잘 정의된 지점에서 실행됩니다.

**참고**  
 인터셉터는 기존 미들웨어 시스템을 기반으로 구축되므로 둘 다 동일한 애플리케이션에서 공존할 수 있습니다. 미들웨어는 전송에 구애받지 않는 동작이나 복잡한 스택 조작이 필요한 고급 사용 사례에 계속 사용할 수 있습니다.

## 사용 가능한 인터셉터 후크
<a name="interceptor-hooks"></a>

 AWS SDK for Go 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>

 각 인터셉터 유형에 적합한 `With*` 옵션과 함께 `config.LoadDefaultConfig` 함수를 사용하여 인터셉터를 전역적으로 등록할 수도 있습니다. 이렇게 하면 해당 구성에서 생성된 모든 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>

 AWS SDK for Go에는 애플리케이션에서 요청 문제 또는 실패를 디버깅하고 진단하기 위한 디버깅 정보를 활성화할 수 있는 로깅 기능이 있습니다. [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>

 기본적으로 서비스 클라이언트는 로그 메시지를 생성하지 않습니다. 디버깅을 위해 로그 메시지를 전송하도록 클라이언트를 구성하려면 `Config`의 [ClientLogMode](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#ClientLogMode) 멤버를 사용합니다. `ClientLogMode`는 다음에 대한 디버깅 메시징을 활성화하도록 설정할 수 있습니다.
+  Signature Version 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>

 AWS SDK for Go 는 SDK 작업에 대한 추적 범위 및 클라이언트 측 지표를 기록하기 위해 계측됩니다. 기본적으로 클라이언트는 추적 및 지표 모두에 대해 no-op 구현을 사용합니다. 즉, 공급자를 구성하지 않는 한 데이터가 수집되지 않습니다.

 서비스 클라이언트에는 관찰성을 위한 두 가지 구성 옵션이 있습니다.
+  [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`. SDK는 구체적인 OTel SDK 구현을 SDK의 공급자 인터페이스에 연결하는 어댑터 모듈을 제공합니다.

## 추적
<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 작업은 요청 직렬화, 서명 및 재시도 루프와 같은 작업 수명 주기의 상위 수준 구성 요소를 포함하는 스팬 계층 구조로 계측됩니다.

## Metrics
<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 | 히스토그램(Histogram) | 재시도, 요청 및 응답 본문을 보내거나 받는 데 걸리는 시간을 포함한 전체 통화 기간입니다. | 
| client.call.attempts | \$1attempt\$1 | MonotonicCounter | 개별 작업에 대한 시도 횟수입니다. | 
| client.call.errors | \$1error\$1 | MonotonicCounter | 작업의 오류 수입니다. | 
| client.call.attempt\$1duration | s | 히스토그램(Histogram) | 서비스에 연결하고, 요청을 보내고, HTTP 상태 코드와 헤더(전송 대기 시간 포함)를 다시 가져오는 시간입니다. | 
| client.call.resolve\$1endpoint\$1duration | s | 히스토그램(Histogram) | 요청에 대한 엔드포인트(DNS가 아닌 엔드포인트 해석기)를 해결하는 시간입니다. | 
| client.call.deserialization\$1duration | s | 히스토그램(Histogram) | 메시지 본문을 역직렬화하는 시간입니다. | 
| client.call.auth.signing\$1duration | s | 히스토그램(Histogram) | 요청에 서명하는 시간입니다. | 
| client.call.auth.resolve\$1identity\$1duration | s | 히스토그램(Histogram) | 자격 증명 공급자로부터 자격 증명(AWS 자격 증명, 보유자 토큰 등)을 획득하는 시간입니다. | 

 해당하는 경우 다음 속성(차원)이 각 지표에 포함됩니다.
+ `rpc.service` - 서비스 이름입니다.
+ `rpc.method` - 작업 이름입니다.
+ `exception.type` - 오류 유형(에 포함됨`client.call.errors`).
+ `auth.scheme_id` - 인증 체계(인증 관련 지표에 포함됨).

### HTTP 클라이언트 지표
<a name="http-client-metrics"></a>

 SDK의 HTTP 클라이언트는 기본 HTTP 연결 수명 주기와 관련된 다음과 같은 추가 지표를 수집합니다.


| 지표 이름 | 단위 | Type | 설명 | 
| --- | --- | --- | --- | 
| client.http.connections.acquire\$1duration | s | 히스토그램(Histogram) | 요청을 통해 연결을 획득하는 데 걸리는 시간입니다. | 
| client.http.connections.dns\$1lookup\$1duration | s | 히스토그램(Histogram) | DNS 조회를 수행하는 데 걸리는 시간입니다. | 
| client.http.connections.tls\$1handshake\$1duration | s | 히스토그램(Histogram) | TLS 핸드셰이크를 수행하는 데 걸리는 시간입니다. | 
| client.http.connections.usage | \$1연결\$1 | UpDownCounter | 풀의 현재 연결 상태입니다. 값이 idle 또는 인 state차원을 사용합니다acquired. | 
| client.http.do\$1request\$1duration | s | 히스토그램(Histogram) | HTTP 요청을 수행하는 데 소요된 총 시간입니다. | 
| client.http.time\$1to\$1first\$1byte | s | 히스토그램(Histogram) | 요청 전송부터 첫 번째 응답 바이트 수신까지의 시간입니다. | 

# 재시도 및 제한 시간
<a name="configure-retries-timeouts"></a>

 를 AWS SDK for Go 사용하면 HTTP 서비스에 대한 요청의 재시도 동작을 구성할 수 있습니다. 기본적으로 서비스 클라이언트는 [retry.Standard](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#Standard)를 기본 재시도기로 사용합니다. 기본 구성 또는 동작이 애플리케이션 요구 사항을 충족하지 않는 경우 재시도기 구성을 조정하거나 자체 재시도기 구현을 제공할 수 있습니다.

 는 구현을 위한 재[시도 구현에 필요한 메서드 세트를 정의하는 aws.Retryer](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Retryer) 인터페이스를 AWS SDK for Go 제공합니다. SDK는 재시도에 대해 [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) 재시도기는 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) 패키지 설명서 예제를 참조하세요.

**주의**  
 `config.WithRetryer`를 사용하여 전역 `aws.Retryer` 구현을 지정하는 경우 `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` 구현을 래핑하여 최대 시도 횟수를 원하는 값으로 설정합니다.

**주의**  
 값이 0인 `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를 직접 설정하는 기능 옵션을 사용하여 재시도를 인스턴스화하면 동작이 약간 다릅니다. 보다 구체적으로, 값을 0보다 작거나 같게 설정하면 재시도자가 무한히 재시도하지 않고 기본 최대 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>

 는 최신 SDK의 동작에 맞게 표준 재시도 정책에 새로운 클라이언트 측 속도 제한 메커니즘을 AWS SDK for Go 도입합니다. 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](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/ratelimit#NewTokenRateLimit)을 사용하여 StandardOptions에서 RateLimiter 값 설정) 
+  제한 시간 비용으로 인한 재시도는 토큰 10개(StandardOptions에서 RetryTimeoutCost 설정) 
+  다른 오류로 인한 재시도 비용은 토큰 5개(StandardOptions에서 RetryCost 설정) 
+  첫 번째 시도에서 성공하는 작업은 토큰 1개 추가(StandardOptions에서 NoRetryIncrement 설정) 
  +  두 번째 이상 시도에서 성공한 작업은 토큰을 다시 추가하지 않음 

 기본 동작이 애플리케이션의 요구 사항에 맞지 않는 경우 [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/) 패키지를 사용하여 서비스 클라이언트 작업을 간접적으로 호출할 때 제한 시간 또는 기한을 설정합니다. [context.WithDeadline](https://golang.org/pkg/context/#WithDeadline)을 사용하여 애플리케이션 컨텍스트를 래핑하고 간접 호출된 작업을 완료해야 하는 특정 시간으로 기한을 설정합니다. 특정 `time.Duration` 사용 [context.WithTimeout](https://golang.org/pkg/context/#WithTimeout) 이후에 제한 시간을 설정하려면 다음을 수행합니다. SDK는 서비스 API를 간접적으로 호출할 때 제공된 `context.Context`를 HTTP 전송 클라이언트에 전달합니다. 작업을 간접 호출하는 동안 SDK에 전달된 컨텍스트가 취소되었거나 취소될 예정이면 SDK는 요청을 더 이상 재시도하지 않고 호출 애플리케이션으로 돌아갑니다. 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
}
```