Lambda Extras

用于使用 AWS Lambda 的 Swifty 辅助工具。

📱 要求

Swift 5.9 工具链,以及 Swift Package Manager。

🖥 安装

Lambda Extras 使用 Swift Package Manager 分发。 要将其安装到项目中,请将其作为依赖项添加到您的 Package.swift 清单中

dependencies: [
    .package(url: "https://github.com/Mobelux/swift-lambda-extras.git", from: "0.1.0")
]

然后,将相关产品添加到需要访问该库的任何目标

.product(name: "<product>", package: "swift-lambda-extras"),

其中 <product> 是以下之一

⚙️ 用法

此包旨在支持创建由 2 部分组成的 lambda

处理程序 (Handler)

创建一个没有 AWS 依赖项的目标,例如 AWSLambdaRuntimeAWSLambdaEvents,以实现 lambda 的核心逻辑。 添加一个类型来表示将在 lambda 中使用的所有环境变量

public enum Environment: String {
    case multiplier = "MULTIPLIER"
    ...
}

以及处理程序输入模型,以及可选的输出模型

public struct Multiplicand: Codable {
    public let value: Int

    public init(value: Int) {
        self.value = value
    }
}

以及一个处理程序来实现 lambda 的核心逻辑

public struct MultiplyHandler {
    public init<C>(
        context: C
    ) async throws where C: InitializationContext, C: EnvironmentValueProvider<Environment> {
        // create any dependencies

        context.handleShutdown { eventLoop in
            // shut dependencies down ...
        }
    }

    public func handle<C>(
        _ event: Multiplicand,
        context: C
    ) async throws -> Int where C: RuntimeContext, C: EnvironmentValueProvider<Environment> {
        let multiplier = try context.value(for: .multiplier)
        return event.value * multiplier
    }
}

Lambda

创建一个可执行目标,并为 LambdaInitializationContextLambdaContext 声明 EnvironmentValueProvider 一致性

extension LambdaInitializationContext: EnvironmentValueProvider {
    public typealias EnvironmentVariable = Environment
}

extension LambdaContext: EnvironmentValueProvider {
    public typealias EnvironmentVariable = Environment
}

并使用像 APIGatewayCoder 这样的 LambdaCoding 类型实现一个 LambdaHandler,该类型使用上面创建的处理程序

@main
struct MultiplyLambda: LambdaHandler {
    let coder: APIGatewayCoder<Multiplicand, Int>
    let handler: MultiplyHandler

    init(context: LambdaInitializationContext) async throws {
        self.coder = APIGatewayCoder()
        self.handler = try await MultiplyHandler(context: context)
    }

    func handle(_ event: APIGatewayV2Request, context: LambdaContext) async throws -> APIGatewayV2Response {
        context.logger.info("RECEIVED: \(event)")
        do {
            let subscription = try await coder.decode(event: event)

            let output = try await handler.handle(subscription, context: context)
            context.logger.info("FINISHED: \(output)")

            return try coder.encode(output: output)
        } catch {
            context.logger.error("UNDERLYING ERROR: \(error.localizedDescription)")
            return try coder.encode(error: error)
        }
    }
}