Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM swift:6.2.0
FROM swift:6.2.3

RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends make git
3 changes: 1 addition & 2 deletions .github/workflows/swift-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ jobs:
strategy:
matrix:
image:
- swift:6.1.2
- swift:6.2.0
- swift:6.2.3
services:
localstack:
image: localstack/localstack
Expand Down
11 changes: 7 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 6.1
// swift-tools-version: 6.2

import PackageDescription

Expand Down Expand Up @@ -31,14 +31,16 @@ let package = Package(
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.0.0"),
.package(url: "https://github.com/soto-project/soto.git", from: "7.0.0"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.6.2"),
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),
.package(url: "https://github.com/apple/swift-configuration", from: "1.0.0")
],
targets: [
.executableTarget(
name: "BreezeLambdaItemAPI",
dependencies: [
"BreezeLambdaAPI"
]
"BreezeLambdaAPI",
.product(name: "Configuration", package: "swift-configuration")
],
resources: [.copy("Resources")]
),
.target(
name: "BreezeDynamoDBService",
Expand All @@ -54,6 +56,7 @@ let package = Package(
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
.product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"),
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle"),
.product(name: "Configuration", package: "swift-configuration"),
"BreezeDynamoDBService"
]
),
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
Add the dependency `BreezeLambdaDynamoDBAPI` to a package:

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

import PackageDescription
Expand Down
45 changes: 31 additions & 14 deletions Sources/BreezeLambdaAPI/BreezeAPIConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@

import SotoDynamoDB
import BreezeDynamoDBService
import AWSLambdaRuntime
import Configuration

/// Defines the configuration for the Breeze Lambda API.
public protocol APIConfiguring {
public protocol APIConfiguring: Sendable {
var dbTimeout: Int64 { get }
func operation() throws -> BreezeOperation
func getConfig() throws -> BreezeDynamoDBConfig
Expand All @@ -26,11 +26,30 @@ public protocol APIConfiguring {
/// - `DYNAMO_DB_TABLE_NAME`: The name of the DynamoDB table.
/// - `DYNAMO_DB_KEY`: The name of the primary key in the DynamoDB table.
public struct BreezeAPIConfiguration: APIConfiguring {
private enum Keys {
static let handler: ConfigKey = "_HANDLER"
static let awsRegion: ConfigKey = "AWS_REGION"
static let tableName: ConfigKey = "DYNAMO_DB_TABLE_NAME"
static let keyName: ConfigKey = "DYNAMO_DB_KEY"
static let localstackEndpoint: ConfigKey = "LOCALSTACK_ENDPOINT"
static let dbTimeout: ConfigKey = "BREEZE_DB_TIMEOUT"
}

public init() {}
private let reader: ConfigReader

/// Timeout for database operations in seconds.
public let dbTimeout: Int64 = 30
/// Creates the configuration using the supplied providers. Defaults to environment variables.
public init(
reader: ConfigReader = ConfigReader(
providers: [EnvironmentVariablesProvider()]
)
) {
self.reader = reader
}

/// Timeout for database operations in seconds, configurable via `BREEZE_DB_TIMEOUT`.
public var dbTimeout: Int64 {
Int64(reader.int(forKey: Keys.dbTimeout, default: 30))
}

/// The operation handler for Breeze operations.
///
Expand All @@ -43,7 +62,7 @@ public struct BreezeAPIConfiguration: APIConfiguring {
///
/// See BreezeOperation for more details.
public func operation() throws -> BreezeOperation {
guard let handler = Lambda.env("_HANDLER"),
guard let handler = reader.string(forKey: Keys.handler),
let operation = BreezeOperation(handler: handler)
else {
throw BreezeLambdaAPIError.invalidHandler
Expand Down Expand Up @@ -78,12 +97,10 @@ public struct BreezeAPIConfiguration: APIConfiguring {
///
/// This method is used to determine the AWS region where the DynamoDB table is located.
func currentRegion() -> Region {
if let awsRegion = Lambda.env("AWS_REGION") {
let value = Region(rawValue: awsRegion)
return value
} else {
return .useast1
if let awsRegion = reader.string(forKey: Keys.awsRegion) {
return Region(rawValue: awsRegion)
}
return .useast1
}

/// Returns the DynamoDB table name from the `DYNAMO_DB_TABLE_NAME` environment variable.
Expand All @@ -92,7 +109,7 @@ public struct BreezeAPIConfiguration: APIConfiguring {
/// This method is used to retrieve the name of the DynamoDB table that will be used by the Breeze Lambda API.
/// - Important: The table name is essential for performing operations on the DynamoDB table.
func tableName() throws -> String {
guard let tableName = Lambda.env("DYNAMO_DB_TABLE_NAME") else {
guard let tableName = reader.string(forKey: Keys.tableName) else {
throw BreezeLambdaAPIError.tableNameNotFound
}
return tableName
Expand All @@ -104,7 +121,7 @@ public struct BreezeAPIConfiguration: APIConfiguring {
/// This method is used to retrieve the name of the primary key in the DynamoDB table that will be used by the Breeze Lambda API.
/// - Important: The key name is essential for identifying items in the DynamoDB table.
func keyName() throws -> String {
guard let keyName = Lambda.env("DYNAMO_DB_KEY") else {
guard let keyName = reader.string(forKey: Keys.keyName) else {
throw BreezeLambdaAPIError.keyNameNotFound
}
return keyName
Expand All @@ -120,7 +137,7 @@ public struct BreezeAPIConfiguration: APIConfiguring {
/// - To set it you need to set the `LOCALSTACK_ENDPOINT` environment variable to the URL of your LocalStack instance.
/// - The Default LocalStack endpoint is `http://localhost:4566`
func endpoint() -> String? {
if let localstack = Lambda.env("LOCALSTACK_ENDPOINT"),
if let localstack = reader.string(forKey: Keys.localstackEndpoint),
!localstack.isEmpty {
return localstack
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/BreezeLambdaAPI/BreezeLambdaAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public actor BreezeLambdaAPI<T: BreezeCodable>: Service {
let breezeApi = BreezeLambdaHandler<T>(dbManager: dbManager, operation: operation)
let runtime = LambdaRuntime(body: breezeApi.handle)
self.serviceGroup = ServiceGroup(
services: [runtime, dynamoDBService],
services: [dynamoDBService, runtime],
gracefulShutdownSignals: [.sigint],
cancellationSignals: [.sigterm],
logger: logger
Expand Down
2 changes: 1 addition & 1 deletion Sources/BreezeLambdaAPI/Docs.docc/Docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public protocol BreezeCodable: Codable, Sendable {
### Add the dependency

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

import PackageDescription
Expand Down
28 changes: 9 additions & 19 deletions Sources/BreezeLambdaItemAPI/BreezeLambdaItemAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import Configuration
import BreezeLambdaAPI
import BreezeDynamoDBService

Expand Down Expand Up @@ -39,31 +40,20 @@ struct Item: Codable {
/// BreezeCodable is a protocol that allows the Item struct to be used with Breeze Lambda API.
extension Item: BreezeCodable { }

/// APIConfiguration is a struct that conforms to APIConfiguring.
/// It provides the configuration for the Breeze Lambda API, including the DynamoDB table name, key name, and endpoint.
/// It also specifies the operation to be performed, which in this case is listing items.
struct APIConfiguration: APIConfiguring {
let dbTimeout: Int64 = 30
func operation() throws -> BreezeOperation {
.list
}

/// Get the configuration for the DynamoDB service.
/// It specifies the region, table name, key name, and endpoint.
/// In this example, it uses a local Localstack endpoint for testing purposes.
/// You can change the region, table name, key name, and endpoint as needed for your application.
/// Remove the endpoint for production use.
func getConfig() throws -> BreezeDynamoDBConfig {
BreezeDynamoDBConfig(region: .useast1, tableName: "Breeze", keyName: "itemKey", endpoint: "http://localstack:4566")
}
}

@main
struct BreezeLambdaItemAPI {
static func main() async throws {
#if DEBUG
do {
let lambdaAPIService = try await BreezeLambdaAPI<Item>(apiConfig: APIConfiguration())
let config = ConfigReader(
providers: [
EnvironmentVariablesProvider(),
try await FileProvider<JSONSnapshot>(filePath: "Sources/BreezeLambdaItemAPI/Resources/breeze-item-config.json")
]
)
let configuration = BreezeAPIConfiguration(reader: config)
let lambdaAPIService = try await BreezeLambdaAPI<Item>(apiConfig: configuration)
try await lambdaAPIService.run()
} catch {
print(error.localizedDescription)
Expand Down
8 changes: 8 additions & 0 deletions Sources/BreezeLambdaItemAPI/Resources/breeze-item-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"_HANDLER": "BreezeLambdaItemAPI.create",
"AWS_REGION": "us-east-1",
"DYNAMO_DB_TABLE_NAME": "Breeze",
"DYNAMO_DB_KEY": "itemKey",
"LOCALSTACK_ENDPOINT": "http://localstack:4566",
"BREEZE_DB_TIMEOUT": 30
}