Rust AWS Smithy实验性插件库aws-smithy-experimental的使用,探索AWS服务开发的实验性工具与扩展功能

Rust AWS Smithy实验性插件库aws-smithy-experimental的使用,探索AWS服务开发的实验性工具与扩展功能

aws-smithy-experimental

Smithy-rs生态系统中实验性新功能的试验场。

Hyper 1.0支持

该库允许客户使用Hyper 1.0。一个有价值的结果是能够访问aws-lc-rs及其符合FIPS标准的加密。这可通过crypto-aws-lc-fips功能获得。注意:FIPS支持有比较复杂的构建要求,即需要CMake和Go。

库稳定化

该库增加了对Hyper 1.0的支持。在稳定化之前有几个阻碍:

  1. 暴露一个提供自定义连接器的API。目前该API未被暴露,因为需要避免对hyper-util的硬依赖。
  2. 在连接池中添加支持以标记连接为不可用。此API需要被反向移植到hyper-util中,或者我们需要建立自己的客户端。

完整示例代码

下面是一个使用aws-smithy-experimental库的完整示例:

use aws_smithy_http::body::SdkBody;
use aws_smithy_http::result::ConnectorError;
use aws_smithy_http::retry::ClassifyResponse;
use aws_smithy_types::retry::RetryKind;
use http::{Request, Response};
use std::future::Future;
use std::pin::Pin;

// 定义一个简单的HTTP客户端
struct SimpleHttpClient;

impl tower::Service<Request<SdkBody>> for SimpleHttpClient {
    type Response = Response<SdkBody>;
    type Error = ConnectorError;
    type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;

    fn poll_ready(
        &mut self,
        _cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Result<(), Self::Error>> {
        std::task::Poll::Ready(Ok(()))
    }

    fn call(&mut self, req: Request<SdkBody>) -> Self::Future {
        Box::pin(async move {
            Ok(Response::builder()
                .status(200)
                .body(SdkBody::from("Hello, world!"))
                .unwrap())
        })
    }
}

// 定义重试分类器
struct SimpleRetryClassifier;

impl ClassifyResponse for SimpleRetryClassifier {
    fn classify(&self, _response: &Result<Response<SdkBody>, ConnectorError>) -> RetryKind {
        RetryKind::NotRetryable
    }
}

#[tokio::main]
async fn main() {
    // 创建客户端
    let client = SimpleHttpClient;
    
    // 构建请求
    let request = Request::builder()
        .uri("http://example.com")
        .body(SdkBody::empty())
        .unwrap();
    
    // 发送请求
    let response = client.call(request).await.unwrap();
    
    // 打印响应状态
    println!("Response status: {}", response.status());
    
    // 读取响应体
    let body = hyper::body::to_bytes(response::into_body()).await.unwrap();
    println!("Response body: {:?}", String::from_utf8_lossy(&body));
}

安装

在项目目录中运行以下Cargo命令:

cargo add aws-smithy-experimental

或者在Cargo.toml中添加以下行:

aws-smithy-experimental = "0.2.0"

特性

  • crypto-aws-lc-fips: 启用FIPS兼容的加密支持
  • hyper-1: 启用Hyper 1.0支持

注意事项

  • 该库处于实验阶段,API可能会发生变化
  • FIPS支持需要额外的构建工具(CMake和Go)
  • 目前对自定义连接器的支持有限

该库是AWS SDK for Rust和smithy-rs代码生成器的一部分。


1 回复

Rust AWS Smithy实验性插件库aws-smithy-experimental使用指南

概述

aws-smithy-experimental是AWS官方提供的Rust实验性插件库,用于扩展AWS SDK for Rust的功能。它基于Smithy模型构建,提供了一些尚未纳入稳定版SDK的实验性功能和工具。

主要功能

  1. 实验性AWS服务客户端支持
  2. 扩展的中间件功能
  3. 自定义请求/响应处理
  4. 高级配置选项

使用方法

添加依赖

首先在Cargo.toml中添加依赖:

[dependencies]
aws-smithy-experimental = "0.1.0"  # 使用最新版本
aws-config = "0.55.0"
aws-sdk-s3 = "0.24.0"  # 或其他AWS服务

基本使用示例

use aws_smithy_experimental::client::experimental_client::ExperimentalClient;
use aws_sdk_s3::Client as S3Client;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建标准AWS配置
    let config = aws_config::load_from_env().await;
    
    // 创建实验性客户端
    let experimental_client = ExperimentalClient::new();
    
    // 包装标准S3客户端
    let s3_client = S3Client::new(&config);
    let wrapped_client = experimental_client.wwrap(s3_client);
    
    // 使用包装后的客户端
    let buckets = wrapped_client.list_buckets().send().await?;
    println!("Buckets: {:?}", buckets.buckets);
    
    Ok(())
}

自定义中间件示例

use aws_smithy_experimental::middleware::MiddlewareLayer;
use aws_smithy_http::operation::Request;
use tower::Layer;

struct LoggingMiddleware;

impl<S> tower::Service<Request> for LoggingMiddleware<S>
where
    S: tower::Service<Request>,
{
    type Response = S::Response;
    type Error = S::Error;
    type Future = S::Future;

    fn poll_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll<Result<(), Self::Error>> {
        self.inner.poll_ready(cx)
    }

    fn call(&mut self, req: Request) -> Self::Future {
        println!("Request: {:?}", req);
        self.inner.call(req)
    }
}

#[tokio::main]
async fn main() {
    let config = aws_config::load_from_env().await;
    let experimental_client = ExperimentalClient::new()
        .with_middleware(MiddlewareLayer::new(LoggingMiddleware));
    
    let s3_client = S3Client::new(&config);
    let wrapped_client = experimental_client.wrap(s3_client);
    
    // 使用带有日志中间件的客户端
    let _ = wrapped_client.list_buckets().send().await;
}

实验性功能标志

use aws_smithy_experimental::features::ExperimentalFeatures;

let experimental_client = ExperimentalClient::new()
    .with_feature(ExperimentalFeatures::NewRetryStrategy)
    .with_feature(ExperimentalFeatures::EnhancedMetrics);

注意事项

  1. 这是一个实验性库,API可能会频繁变更
  2. 不建议在生产环境中使用
  3. 某些功能可能不稳定或未经充分测试
  4. 使用前请查看最新文档了解兼容性

完整示例代码

下面是一个结合多个功能的完整示例:

use aws_smithy_experimental::{
    client::experimental_client::ExperimentalClient,
    middleware::MiddlewareLayer,
    retry::ExperimentalRetryStrategy,
    features::ExperimentalFeatures,
    transform::{RequestTransform, ResponseTransform}
};
use aws_sdk_s3::Client as S3Client;
use aws_smithy_http::operation::Request;
use std::time::Duration;
use tower::Layer;

// 自定义日志中间件
struct LoggingMiddleware;

impl<S> tower::Service<Request> for LoggingMiddleware<S>
where
    S: tower::Service<Request>,
{
    type Response = S::Response;
    type Error = S::Error;
    type Future = S::Future;

    fn poll_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll<Result<(), Self::Error>> {
        self.inner.poll_ready(cx)
    }

    fn call(&mut self, req: Request) -> Self::Future {
        println!("[LOG] Request started: {:?}", req);
        self.inner.call(req)
    }
}

// 请求转换器 - 添加自定义头
fn add_custom_header(mut req: Request) -> Request {
    req.http_mut()
        .headers_mut()
        .insert("X-Custom-Header", "value".parse().unwrap());
    req
}

// 响应转换器 - 记录响应状态
fn log_response_status(res: aws_smithy_http::operation::Response) -> aws_smithy_http::operation::Response {
    println!("[LOG] Response status: {}", res.http().status());
    res
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 加载AWS配置
    let config = aws_config::load_from_env().await;
    
    // 创建自定义重试策略
    let retry_strategy = ExperimentalRetryStrategy::new()
        .with_max_attempts(3)
        .with_backoff(Duration::from_secs(2));
    
    // 创建实验性客户端并配置各种功能
    let experimental_client = ExperimentalClient::new()
        .with_middleware(MiddlewareLayer::new(LoggingMiddleware))
        .with_retry_strategy(retry_strategy)
        .with_feature(ExperimentalFeatures::EnhancedMetrics)
        .with_request_transform(RequestTransform::new(add_custom_header))
        .with_response_transform(ResponseTransform::new(log_response_status));
    
    // 包装标准S3客户端
    let s3_client = S3Client::new(&config);
    let wrapped_client = experimental_client.wrap(s3_client);
    
    // 使用包装后的客户端执行操作
    let result = wrapped_client.list_buckets().send().await?;
    
    println!("操作完成,获取到 {} 个bucket", result.buckets.len());
    
    Ok(())
}

这个完整示例展示了如何:

  1. 创建自定义中间件记录请求日志
  2. 配置自定义重试策略
  3. 启用实验性功能(增强指标)
  4. 添加请求/响应转换器
  5. 包装标准S3客户端并使用增强后的功能

建议定期查看AWS官方Rust SDK的更新日志,了解实验性功能何时会被纳入稳定版本。

回到顶部