

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在中配置客户端终端节点 适用于 Rust 的 AWS SDK
<a name="endpoints"></a>

当 适用于 Rust 的 AWS SDK 调用 a 时 AWS 服务，其第一步之一就是确定将请求路由到何处。此过程称为端点解析。

在创建服务客户端时，您可以为 SDK 配置端点解析。端点解析的默认配置通常没问题，但您可能出于多种原因需要修改默认配置。两个示例原因如下所示：
+ 向服务的预发行版本或服务的本地部署发出请求。
+ 访问尚未在 SDK 中建模的特定服务功能。

**警告**  
端点解析是一个高级 SDK 主题。如果您更改默认设置，则可能会破坏代码。默认设置应用于生产环境中的大多数用户。

可以全局设置自定义终端节点，以便它们用于所有服务请求，也可以为特定的终端节点设置自定义终端节点 AWS 服务。

可以使用共享 AWS `config`文件中的环境变量或设置来配置自定义终端节点。有关此方法的信息，请参阅《工具参考指南》*AWS SDKs 和《工具参考指南*》中的[服务特定端点](https://docs.aws.amazon.com/sdkref/latest/guide/feature-ss-endpoints.html)。有关所有共享`config`文件设置和环境变量的完整列表 AWS 服务，请参阅[服务特定端点的标识符](https://docs.aws.amazon.com/sdkref/latest/guide/ss-endpoints-table.html)。

 或者，您也可以在代码中配置此自定义选项，如以下部分所示。

## 自定义配置
<a name="custom-configuration"></a>

您可以使用在构建客户端时可用的两种方法来自定义服务客户端的端点解析：

1. `endpoint_url(url: Into<String>)`

1. `endpoint_resolver(resolver: impl crate::config::endpoint::ResolveEndpoint + `static)`

您可以设置这两个属性。但是，大多数情况下，您只提供一个。对于常规使用情况，`endpoint_url` 通常需要自定义。

### 设置端点 URL
<a name="set-endpoint-url"></a>

您可以为 `endpoint_url` 设置一个值来表示服务的“基本”主机名。但是，此值不是最终值，因为它是作为参数传递给客户端 `ResolveEndpoint` 实例的。然后，`ResolveEndpoint` 实现会检查该值，并可能修改该值以确定最终端点。

### 设置端点解析器
<a name="set-endpoint-resolver"></a>

服务客户端的 `ResolveEndpoint` 实现决定了 SDK 用于任何给定请求的最终解析端点。服务客户端为每个请求调用 `resolve_endpoint` 方法，并使用解析器返回的 [https://docs.rs/aws-smithy-runtime-api/latest/aws_smithy_runtime_api/client/endpoint/struct.EndpointFuture.html](https://docs.rs/aws-smithy-runtime-api/latest/aws_smithy_runtime_api/client/endpoint/struct.EndpointFuture.html) 值，而不做任何更改。

以下示例演示了如何为 Amazon S3 客户端提供自定义端点解析器实现，该实现会根据不同的阶段（例如暂存和生产）解析不同的端点：

```
use aws_sdk_s3::config::endpoint::{ResolveEndpoint, EndpointFuture, Params, Endpoint};

#[derive(Debug)]
struct StageResolver { stage: String }
impl ResolveEndpoint for StageResolver {
    fn resolve_endpoint(&self, params: &Params) -> EndpointFuture<'_> {
        let stage = &self.stage;
        EndpointFuture::ready(Ok(Endpoint::builder().url(format!("{stage}.myservice.com")).build()))
    }
}


let config = aws_config::defaults(BehaviorVersion::latest())
    .load()
    .await;

let resolver = StageResolver { stage: std::env::var("STAGE").unwrap() };

let s3_config = aws_sdk_s3::config::Builder::from(&config)
    .endpoint_resolver(resolver)
    .build();

let s3 = aws_sdk_s3::Client::from_conf(s3_config);
```

**注意**  
端点解析器以及由此扩展的 `ResolveEndpoint` 特性是每个服务特有的，因此只能在服务客户端配置中进行配置。另一方面，可以使用共享配置（应用于从中派生的所有服务）或针对特定服务配置端点 URL。

#### ResolveEndpoint 参数
<a name="resolveendpoint-parameters"></a>

`resolve_endpoint` 方法接受包含端点解析中使用的属性的服务特定参数。

每个服务均包含以下基本属性：


| Name | Type | 说明 | 
| --- | --- | --- | 
| region | 字符串 | 客户的 AWS 区域 | 
| endpoint | 字符串 | endpointUrl 的值集的字符串表示形式 | 
| use\$1fips | 布尔值 | 是否在客户端配置中启用了 FIPS 端点 | 
| use\$1dual\$1stack | 布尔值 | 是否在客户端配置中启用了双栈端点 | 

AWS 服务 可以指定解析所需的其他属性。例如，Amazon S3 [端点参数](https://docs.rs/aws-sdk-s3/latest/aws_sdk_s3/config/endpoint/struct.Params.html)包括存储桶名称和几个特定于 Amazon S3 的功能设置。例如，`force_path_style` 属性决定是否可以使用虚拟主机寻址。

如果您实施自己的提供程序，则无需构建自己的端点参数实例。SDK 为每个请求提供属性并将其传递给您的 `resolve_endpoint` 实现。

### 将使用 `endpoint_url` 与使用 `endpoint_resolver` 进行比较
<a name="endpoint-url-or-endpoint-resolver"></a>

需要注意的是，以下两种配置（一种使用 `endpoint_url`，另一种使用 `endpoint_resolver`）产生的客户端在端点解析行为上并不相同。

```
use aws_sdk_s3::config::endpoint::{ResolveEndpoint, EndpointFuture, Params, Endpoint};

#[derive(Debug, Default)]
struct CustomResolver;
impl ResolveEndpoint for CustomResolver {
    fn resolve_endpoint(&self, _params: &Params) -> EndpointFuture<'_> {
        EndpointFuture::ready(Ok(Endpoint::builder().url("https://endpoint.example").build()))
    }
}

let config = aws_config::defaults(BehaviorVersion::latest())
    .load()
    .await;

// use endpoint url
aws_sdk_s3::config::Builder::from(&config)
    .endpoint_url("https://endpoint.example")
    .build();
    
// Use endpoint resolver
aws_sdk_s3::config::Builder::from(&config)
    .endpoint_resolver(CustomResolver::default())
    .build();
```

设置 `endpoint_url` 的客户端会指定传递给（默认）提供程序的*基本* URL，该 URL 可以作为端点解析的一部分进行修改。

设置 `endpoint_resolver` 的客户端指定 Amazon S3 客户端使用的*最终* URL。

## 示例
<a name="endpointsExamples"></a>

自定义端点通常用于测试。不是向基于云的服务发送调用，而是将调用路由到本地托管的模拟服务。其中两种选项是：
+ [DynamoDB local](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html) – Amazon DynamoDB 服务的本地版本。
+ [LocalStack](https://github.com/localstack/localstack)— 在本地计算机的容器中运行的云服务模拟器。

 以下示例说明了指定自定义端点以使用这两个测试选项的两种不同方法。

### 直接在代码中使用 DynamoDB local
<a name="endpointsExamplesddb"></a>

如前几节所述，您可以直接在代码中设置 `endpoint_url` 来覆盖基本端点，以便指向本地 DynamoDB 服务器。在代码中：

```
    let config = aws_config::defaults(aws_config::BehaviorVersion::latest())
        .test_credentials()
        // DynamoDB run locally uses port 8000 by default.
        .endpoint_url("http://localhost:8000")
        .load()
        .await;
    let dynamodb_local_config = aws_sdk_dynamodb::config::Builder::from(&config).build();

    let client = aws_sdk_dynamodb::Client::from_conf(dynamodb_local_config);
```

[完整的示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/rustv1/examples/dynamodb/src/bin/list-tables-local.rs)可在上找到 GitHub。

### LocalStack 使用该`config`文件
<a name="endpointsExamplesLs"></a>

您可以在共享 AWS `config`文件中设置[特定于服务的终端节点](https://docs.aws.amazon.com/sdkref/latest/guide/feature-ss-endpoints.html)。以下配置的配置文件将 `endpoint_url` 设置为连接到端口 `4566` 上的 `localhost`。有关 LocalStack 配置的更多信息，请参阅*LocalStack文档*网站[上的 LocalStack 通过端点 URL 进行访问](https://docs.localstack.cloud/references/network-troubleshooting/endpoint-url/)。

```
[profile localstack]
region=us-east-1
endpoint_url = http://localhost:4566
```

当您使用 `localstack` 配置文件时，SDK 将获取共享 `config` 文件中的更改并将其应用到您的 SDK 客户端。使用这种方法，您的代码无需包含对端点的任何引用，如下所示：

```
    // set the environment variable `AWS_PROFILE=localstack` when running
    // the application to source `endpoint_url` and point the SDK at the
    // localstack instance
    let config = aws_config::defaults(BehaviorVersion::latest()).load().await;

    let s3_config = aws_sdk_s3::config::Builder::from(&config)
        .force_path_style(true)
        .build();

    let s3 = aws_sdk_s3::Client::from_conf(s3_config);
```

[完整的示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/rustv1/examples/localstack)可在上找到 GitHub。