Build - main Branch Swift 5.6, 5.7 and 5.8 Tested Join the Smoke Server Side community on gitter Apache 2

SmokeAWSGenerate

SmokeAWSGenerate 主要提供一个代码生成器,它使用 Open API/Swagger 模型为 AWS API Gateway 托管的端点生成 Swift 客户端包。

默认情况下,生成器将在 Swift 客户端包中创建两个 target:Model target 和 Client target。

步骤 1:准备新 Swift 客户端的位置

这可能是一个 Github 仓库或其他仓库。 检出此位置,以便您可以向其添加文件。

步骤 2:准备您的 OpenAPI 3.0 或 Swagger 模型

根据您的用例,此模型可以与 Swift 客户端托管在同一个 Swift 包中,也可以托管在单独的包中。

步骤 1A:模型在同一个 Swift 包中

对于同一 Swift 包中的模型,只需根据 Open API 规范Swagger 规范创建模型即可。 通常,此模型将位于客户端包的根目录中。

步骤 1B:模型在单独的 Swift 包中

如果模型托管在单独的 Swift 包中,则需要将模型文件指定为该包的资源。 以下显示了模型包所需的最小 Swift Package 清单。

// swift-tools-version: 5.6
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "ServiceModel",
    products: [
        .library(
            name: "ServiceModel",
            targets: ["ServiceModel"]),
    ],
    targets: [
        .target(
            name: "ServiceModel",
            dependencies: [],
            path: "api",
            resources: [.copy("OpenAPI30.yaml")]),
    ]
)

如果需要,此模型包可以包含其他产品和 target。 如果您的模型包仅包含您的模型文件(例如,如果您想在您的服务和客户端包之间独立于任何其他内容共享您的模型),由于 SwiftPM 的当前限制,您需要在 target 的基本目录中添加一个空的 Swift 文件(在本例中为 /api)

然后,根据 Open API 规范Swagger 规范创建模型。

步骤 2:生成客户端包

克隆此仓库 (smoke-aws-generate),并从其基本目录运行以下命令,并根据需要替换值。

此命令将生成构建客户端包所需的包清单和其他 scaffolding。

步骤 2A:模型在同一个 Swift 包中

swift run APIGatewayClientInitialize -c release --base-file-path <path-to-the-client-package> \
--base-name "PersistenceExample" \
--model-format "OPENAPI3_0" \
--model-path "OpenAPI30.yaml"

步骤 2B:模型在单独的 Swift 包中

swift run APIGatewayClientInitialize -c release --base-file-path <path-to-the-client-package> \
--base-name "PersistenceExample" \
--model-format "OPENAPI3_0" \
--model-path "OpenAPI30.yaml" \
--model-product-dependency "ServiceModel" \
--package-location "https://github.com/example/service-model.git" \
--version-requirement-type "from"
--version-requirement "1.0.0"

注意:使用 Swagger 2.0 模型文件时,--model-format 参数必须使用 SWAGGER

注意:如果托管模型文件的 target 与产品名称不同,您可以选择指定 --model-target-dependency 参数。

您还可以选择指定 --model-target-name--client-target-name 参数来指定自定义 target 名称。 否则,将使用 \(base-name)Model\(base-name)Client

注意:您还可以手动生成 Swift 包清单和结构以及配置文件(参见下一步)。 APIGatewayClientInitialize 可执行文件只是一个方便的工具,不是构建客户端包所必需的。

步骤 3:更新 codegen 配置

作为上一步的一部分,将在客户端包的基本目录中生成一个名为 api-gateway-client-swift-codegen.json 的配置文件。 此文件存储构建时代码生成的配置选项。

{
  "baseName" : "PersistenceExample",
  "modelFormat" : "OPENAPI3_0",
  "modelLocations" : {
    "default" : {
      "modelFilePath" : "OpenAPI30.yaml",
      "modelProductDependency" : "ServiceModel"
    }
  }
}

您可以将以下附加选项添加到此配置文件中:

modelOverridehttpClientConfiguration 字段的 schema 可以在这里找到 - https://github.com/amzn/service-model-swift-code-generate/blob/main/Sources/ServiceModelEntities/ModelOverride.swift

一个示例配置 - 包括 modelOverride 配置 - 可以在这里找到 - https://github.com/amzn/smoke-framework-examples/blob/612fd9dca5d8417d2293a203aca4b02672889d12/PersistenceExampleService/smoke-framework-codegen.json

Shape 协议允许您在不同模型中转换相似的类型。

extension Model1.Location: Model2.LocationShape {}

let model2Location = model1.asModel2Location()

可以如下所示指定 modelTargets 选项。

{
  "baseName" : "PersistenceExample",
  "modelFormat" : "OPENAPI3_0",
  "modelLocations" : {
    "default" : {
      "modelFilePath" : "OpenAPI30.yaml",
      "modelProductDependency" : "ServiceModel"
    }
  },
  "modelTargets": {
      "MyClientTarget": {
          "modelTargetName": "MyModelTarget"
      }
  }
}

步骤 4:依赖客户端包

您现在可以通过依赖 Client target 从其他 Swift 包中使用客户端包。

基本用法

使用客户端的最简单方法是直接初始化它,然后在稍后的某个时间点将其关闭。

let client = APIGatewayPersistenceExampleClient(credentialsProvider: credentialsProvider, 
                                                awsRegion: awsRegion,
                                                endpointHostName: endpointHostName)

...
// Use the client
...

try await client.shutdown()

凭证提供程序需要符合来自 SmokeAWSCore 的 CredentialsProvider 协议Smoke AWS Credentials 提供了用于获取或承担短期轮换 AWS IAM 凭证的实现。

客户端初始化器还可以选择接受 loggertimeoutConfigurationconnectionPoolConfigurationretryConfigurationeventLoopProviderreportingConfiguration

重用配置或底层 HTTP 客户端

对于您想要在实例之间重用底层 HTTP 客户端的用例,您可以使用操作客户端类型(或类似地,使用配置对象类型来共享客户端配置,但不共享底层 HTTP 客户端)。

// Start of application
let operationsClient = APIGatewayPersistenceExampleOperationsClient(credentialsProvider: credentialsProvider, 
                                                                    awsRegion: awsRegion,
                                                                    endpointHostName: endpointHostName)
                                                                    
// Per-request
let client = APIGatewayPersistenceExampleClient(operationsClient: operationsClient,
                                                logger: logger)
// Use the client within the request
// This client doesn't need to be explicitly shutdown 
// as it doesn't own the underlying http client
// client.shutdown() would be a no-op

// End of application
try await operationsClient.shutdown()

使用 Mock 客户端实现进行测试

您可以使用 Mock 和 Throwing Mock 客户端实现进行单元测试。 这些实现符合生成的客户端协议。 在应用程序代码中使用此协议将允许您使用 Mock 客户端进行测试,并使用 API Gateway 客户端进行实际使用。

可以使用单元测试所需的任何逻辑覆盖每个客户端 API。

func testCodeThatUsesGetCustomerDetails() {
    func getCustomerDetails(input: PersistenceExampleModel.GetCustomerDetailsRequest) async throws 
    -> PersistenceExampleModel.CustomerAttributes {
       // mock behaviour of the API
    }
    
    let mockClient = MockPersistenceExampleClient(getCustomerDetails: getCustomerDetails)

    // run a test using the mock client

用于 Web 和服务框架的便捷初始化器

每个客户端还提供一组使用 HTTPClientInvocationAttributes 协议的便捷初始化器,以传递与当前请求/调用关联的 LoggerEventLoopInternalRequestId 和指标聚合器。

例如,当使用 smoke-framework 时,您可以直接将提供的 SmokeServerInvocationReporting 实例传递到客户端的初始化器中。

    public func getInvocationContext(
            invocationReporting: SmokeServerInvocationReporting<SmokeInvocationTraceContext>) -> TheServiceContext {
        let theClient = APIGatewayAnotherServiceClient(operationsClient: self.theOperationsClient, invocationAttributes: invocationReporting)
        
        ...
        
        return TheServiceContext(...
                                 theClient: theClient,
                                 ...)
    }

如果您希望客户端忽略 HTTPClientInvocationAttributes 实例提供的 EventLoop,您可以在配置对象或操作客户端上将 ignoreInvocationEventLoop 设置为 true。 否则,客户端将尝试在与提供的调用相同的事件循环上执行客户端 http 请求。

生成 SmokeAWS 库

SmokeAWSGenerate 可执行文件是 SmokeAWS 库的代码生成器。

步骤 1:检出 SmokeAWS 仓库

将 SmokeAWS 仓库克隆到您的本地计算机。

步骤 2:检出此仓库

将此仓库克隆到您的本地计算机。

步骤 3:运行代码生成器

从您检出的此仓库副本中,运行以下命令:

swift run -c release SmokeAWSGenerate \
  --base-file-path <path_to_the_smoke_aws_repository>

许可证

此库是在 Apache 2.0 许可证下获得许可的。