swift-lambda-extras

0.3.0

Swifty helpers for working with AWS Lambda.
Mobelux/swift-lambda-extras

What's New

0.3.0

2024-01-26T20:05:10Z

What's Changed

Other Changes

  • Update Dependencies and Specify Stable Versions by @mgacy in #9
  • Additional Test Helpers by @mgacy in #10

Full Changelog: 0.2.0...0.3.0

Lambda Extras

Swifty helpers for working with AWS Lambda.

📱 Requirements

Swift 5.7 toolchain with Swift Package Manager.

🖥 Installation

Lambda Extras is distributed using the Swift Package Manager. To install it into a project, add it as a dependency within your Package.swift manifest:

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

Then, add the relevant product to any targets that need access to the library:

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

Where <product> is one of the following:

  • LambdaExtrasCore
  • LambdaExtras
  • LambdaMocks

⚙️ Usage

This package is intended to support the creation of lambdas composed of 2 parts:

  • a generic target with a handler implementing the core logic without AWS dependencies
  • an executable target using that generic one

Handler

Create a target without AWS dependencies like AWSLambdaRuntime or AWSLambdaEvents to implement the the lambda's core logic. Add a type to represent all environment variables that will be used in the lambda:

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

as well as a model for the handler's input and optionally its output:

public struct Multiplicand: Codable {
    public let value: Int

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

and a handler to implement the core logic of the 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

Create an executable target and declare EnvironmentValueProvider conformances for LambdaInitializationContext and LambdaContext:

extension LambdaInitializationContext: EnvironmentValueProvider {
    public typealias EnvironmentVariable = Environment
}

extension LambdaContext: EnvironmentValueProvider {
    public typealias EnvironmentVariable = Environment
}

and implement a LambdaHandler with a LambdaCoding type like APIGatewayCoder that uses the handler created above:

@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)
        }
    }
}

Description

  • Swift Tools 5.7.0
View More Packages from this Author

Dependencies

Last updated: Thu Apr 11 2024 23:58:28 GMT-0900 (Hawaii-Aleutian Daylight Time)