

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# クライアントエンドポイントを設定する
<a name="configure-endpoints"></a>

**警告**  
 エンドポイントの解決は上級者向けの SDK トピックです。これらの設定を変更すると、コードが動作しなくなる可能性があります。デフォルト設定は、本番環境のほとんどのユーザーに適しています。

 AWS SDK for Go は、サービスに使用するカスタムエンドポイントを設定する機能を提供します。ほとんどの場合、デフォルトの設定で十分です。カスタムエンドポイントを設定することで、サービスのプレリリースバージョンとの連携など、追加の動作が可能になります。

## カスタマイズ
<a name="customization"></a>

 SDK では、エンドポイント解決の設定に 2 つの「バージョン」があります。
+  v2。2023 年第 3 四半期にリリース。以下で設定: 
  +  `EndpointResolverV2` 
  +  `BaseEndpoint` 
+  v1。SDK と同時にリリース。以下で設定: 
  +  `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内での一般的なエンドポイント解決を容易にする次の基本パラメータが含まれています。


|  名前  |  型  |  説明  | 
| --- | --- | --- | 
|  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` インターフェイスを実装できます。

 `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) のセンチネルエラー値を使用して、サービスクライアントのデフォルト解決ロジックにフォールバックさせます。これにより、フォールバックロジックを個別に扱うことなく、1 つ以上のエンドポイントを選択的にシームレスにオーバーライドできます。

 エンドポイントリゾルバーが `EndpointNotFoundError` 以外のエラーを返した場合、エンドポイント解決は停止し、サービスオペレーションはアプリケーションにエラーを返します。

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

#### フォールバックあり
<a name="with-fallback"></a>

 DynamoDB の 1 つのサービスエンドポイントをオーバーライドし、他のエンドポイントにはフォールバック動作を適用する方法を示すコードスニペットです。

```
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 の 1 つのサービスエンドポイントをオーバーライドし、他のエンドポイントにはフォールバック動作を適用しない方法を示すコードスニペットです。

```
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` に設定した [Endpoint](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Endpoint) を返すことは、`BaseEndpoint` を v1 から元々返された URL に設定し、`EndpointResolverV2` をデフォルトのままにすることとほぼ同等です。
+  HostnameImmutable を `true` に設定した Endpoint を返すことは、v1 から元々返された URL を返す `EndpointResolverV2` を実装することとほぼ同等です。
  +  主な例外は、エンドポイントのプレフィックスがモデルとして定義されているオペレーションに該当する場合です。これに関する注意点は後述します。

 これらのケースの例を次に示します。

**警告**  
 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)
    }
}
```