Skip to content

Commit 433478e

Browse files
author
Andrea Scuderi
committed
Add swift-configuration dependendency
1 parent 8ed8608 commit 433478e

6 files changed

Lines changed: 94 additions & 36 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ local_setup_dynamo_db:
2929
--region us-east-1
3030

3131
local_invoke_demo_app:
32-
curl -X POST 127.0.0.1:7000/invoke -H "Content-Type: application/json" -d @Tests/BreezeLambdaAPITests/Fixtures/post_products_api_gtw.json
32+
curl -X POST 127.0.0.1:7000/invoke -H "Content-Type: application/json" -d @Sources/BreezeLambdaItemAPI/Resources/post_items_api_gtw.json
3333

3434
test:
3535
swift test --sanitize=thread --enable-code-coverage

Package.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,16 @@ let package = Package(
3232
.package(url: "https://github.com/soto-project/soto.git", from: "7.0.0"),
3333
.package(url: "https://github.com/apple/swift-log.git", from: "1.6.2"),
3434
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),
35+
.package(url: "https://github.com/apple/swift-configuration", from: "1.0.0")
3536
],
3637
targets: [
3738
.executableTarget(
3839
name: "BreezeLambdaItemAPI",
3940
dependencies: [
40-
"BreezeLambdaAPI"
41-
]
41+
"BreezeLambdaAPI",
42+
.product(name: "Configuration", package: "swift-configuration")
43+
],
44+
resources: [.copy("Resources")]
4245
),
4346
.target(
4447
name: "BreezeDynamoDBService",
@@ -54,6 +57,7 @@ let package = Package(
5457
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
5558
.product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"),
5659
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle"),
60+
.product(name: "Configuration", package: "swift-configuration"),
5761
"BreezeDynamoDBService"
5862
]
5963
),

Sources/BreezeLambdaAPI/BreezeAPIConfiguration.swift

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77

88
import SotoDynamoDB
99
import BreezeDynamoDBService
10-
import AWSLambdaRuntime
10+
import Configuration
1111

1212
/// Defines the configuration for the Breeze Lambda API.
13-
public protocol APIConfiguring {
13+
public protocol APIConfiguring: Sendable {
1414
var dbTimeout: Int64 { get }
1515
func operation() throws -> BreezeOperation
1616
func getConfig() throws -> BreezeDynamoDBConfig
@@ -26,11 +26,30 @@ public protocol APIConfiguring {
2626
/// - `DYNAMO_DB_TABLE_NAME`: The name of the DynamoDB table.
2727
/// - `DYNAMO_DB_KEY`: The name of the primary key in the DynamoDB table.
2828
public struct BreezeAPIConfiguration: APIConfiguring {
29+
private enum Keys {
30+
static let handler: ConfigKey = "_HANDLER"
31+
static let awsRegion: ConfigKey = "AWS_REGION"
32+
static let tableName: ConfigKey = "DYNAMO_DB_TABLE_NAME"
33+
static let keyName: ConfigKey = "DYNAMO_DB_KEY"
34+
static let localstackEndpoint: ConfigKey = "LOCALSTACK_ENDPOINT"
35+
static let dbTimeout: ConfigKey = "BREEZE_DB_TIMEOUT"
36+
}
2937

30-
public init() {}
38+
private let reader: ConfigReader
3139

32-
/// Timeout for database operations in seconds.
33-
public let dbTimeout: Int64 = 30
40+
/// Creates the configuration using the supplied providers. Defaults to environment variables.
41+
public init(
42+
reader: ConfigReader = ConfigReader(
43+
providers: [EnvironmentVariablesProvider()]
44+
)
45+
) {
46+
self.reader = reader
47+
}
48+
49+
/// Timeout for database operations in seconds, configurable via `BREEZE_DB_TIMEOUT`.
50+
public var dbTimeout: Int64 {
51+
Int64(reader.int(forKey: Keys.dbTimeout, default: 30))
52+
}
3453

3554
/// The operation handler for Breeze operations.
3655
///
@@ -43,7 +62,7 @@ public struct BreezeAPIConfiguration: APIConfiguring {
4362
///
4463
/// See BreezeOperation for more details.
4564
public func operation() throws -> BreezeOperation {
46-
guard let handler = Lambda.env("_HANDLER"),
65+
guard let handler = reader.string(forKey: Keys.handler),
4766
let operation = BreezeOperation(handler: handler)
4867
else {
4968
throw BreezeLambdaAPIError.invalidHandler
@@ -78,12 +97,10 @@ public struct BreezeAPIConfiguration: APIConfiguring {
7897
///
7998
/// This method is used to determine the AWS region where the DynamoDB table is located.
8099
func currentRegion() -> Region {
81-
if let awsRegion = Lambda.env("AWS_REGION") {
82-
let value = Region(rawValue: awsRegion)
83-
return value
84-
} else {
85-
return .useast1
100+
if let awsRegion = reader.string(forKey: Keys.awsRegion) {
101+
return Region(rawValue: awsRegion)
86102
}
103+
return .useast1
87104
}
88105

89106
/// Returns the DynamoDB table name from the `DYNAMO_DB_TABLE_NAME` environment variable.
@@ -92,7 +109,7 @@ public struct BreezeAPIConfiguration: APIConfiguring {
92109
/// This method is used to retrieve the name of the DynamoDB table that will be used by the Breeze Lambda API.
93110
/// - Important: The table name is essential for performing operations on the DynamoDB table.
94111
func tableName() throws -> String {
95-
guard let tableName = Lambda.env("DYNAMO_DB_TABLE_NAME") else {
112+
guard let tableName = reader.string(forKey: Keys.tableName) else {
96113
throw BreezeLambdaAPIError.tableNameNotFound
97114
}
98115
return tableName
@@ -104,7 +121,7 @@ public struct BreezeAPIConfiguration: APIConfiguring {
104121
/// 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.
105122
/// - Important: The key name is essential for identifying items in the DynamoDB table.
106123
func keyName() throws -> String {
107-
guard let keyName = Lambda.env("DYNAMO_DB_KEY") else {
124+
guard let keyName = reader.string(forKey: Keys.keyName) else {
108125
throw BreezeLambdaAPIError.keyNameNotFound
109126
}
110127
return keyName
@@ -120,7 +137,7 @@ public struct BreezeAPIConfiguration: APIConfiguring {
120137
/// - To set it you need to set the `LOCALSTACK_ENDPOINT` environment variable to the URL of your LocalStack instance.
121138
/// - The Default LocalStack endpoint is `http://localhost:4566`
122139
func endpoint() -> String? {
123-
if let localstack = Lambda.env("LOCALSTACK_ENDPOINT"),
140+
if let localstack = reader.string(forKey: Keys.localstackEndpoint),
124141
!localstack.isEmpty {
125142
return localstack
126143
}

Sources/BreezeLambdaItemAPI/BreezeLambdaItemAPI.swift

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
import Configuration
1516
import BreezeLambdaAPI
1617
import BreezeDynamoDBService
1718

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

42-
/// APIConfiguration is a struct that conforms to APIConfiguring.
43-
/// It provides the configuration for the Breeze Lambda API, including the DynamoDB table name, key name, and endpoint.
44-
/// It also specifies the operation to be performed, which in this case is listing items.
45-
struct APIConfiguration: APIConfiguring {
46-
let dbTimeout: Int64 = 30
47-
func operation() throws -> BreezeOperation {
48-
.list
49-
}
50-
51-
/// Get the configuration for the DynamoDB service.
52-
/// It specifies the region, table name, key name, and endpoint.
53-
/// In this example, it uses a local Localstack endpoint for testing purposes.
54-
/// You can change the region, table name, key name, and endpoint as needed for your application.
55-
/// Remove the endpoint for production use.
56-
func getConfig() throws -> BreezeDynamoDBConfig {
57-
BreezeDynamoDBConfig(region: .useast1, tableName: "Breeze", keyName: "itemKey", endpoint: "http://localstack:4566")
58-
}
59-
}
6043

6144
@main
6245
struct BreezeLambdaItemAPI {
6346
static func main() async throws {
6447
#if DEBUG
6548
do {
66-
let lambdaAPIService = try await BreezeLambdaAPI<Item>(apiConfig: APIConfiguration())
49+
let config = ConfigReader(
50+
providers: [
51+
EnvironmentVariablesProvider(),
52+
try await FileProvider<JSONSnapshot>(filePath: "Sources/BreezeLambdaItemAPI/Resources/breeze-item-config.json")
53+
]
54+
)
55+
let configuration = BreezeAPIConfiguration(reader: config)
56+
let lambdaAPIService = try await BreezeLambdaAPI<Item>(apiConfig: configuration)
6757
try await lambdaAPIService.run()
6858
} catch {
6959
print(error.localizedDescription)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"_HANDLER": "BreezeLambdaItemAPI.create",
3+
"AWS_REGION": "us-east-1",
4+
"DYNAMO_DB_TABLE_NAME": "Breeze",
5+
"DYNAMO_DB_KEY": "itemKey",
6+
"LOCALSTACK_ENDPOINT": "http://localstack:4566",
7+
"BREEZE_DB_TIMEOUT": 30
8+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"body": "{\n \"itemKey\": \"2023\",\n \"name\": \"Swift Serverless API with async/await! 🚀🥳\",\n \"description\": \"BreezeLambaAPI is magic 🪄!\"\n} ",
3+
"headers": {
4+
"accept": "*/*",
5+
"accept-encoding": "gzip, deflate, br",
6+
"cache-control": "no-cache",
7+
"content-length": "137",
8+
"content-type": "application/json",
9+
"host": "br33z3ap10.execute-api.eu-west-1.amazonaws.com",
10+
"postman-token": "7005b89f-915e-4c30-9237-8832e7842f91",
11+
"user-agent": "PostmanRuntime/7.31.0",
12+
"x-amzn-trace-id": "Root=1-63f7d7e5-0381fae826a3075e05564773",
13+
"x-forwarded-for": "140.228.54.79",
14+
"x-forwarded-port": "443",
15+
"x-forwarded-proto": "https"
16+
},
17+
"isBase64Encoded": false,
18+
"rawPath": "/products",
19+
"rawQueryString": "",
20+
"requestContext": {
21+
"accountId": "00000000000",
22+
"apiId": "br33z3ap10",
23+
"domainName": "br33z3ap10.execute-api.eu-west-1.amazonaws.com",
24+
"domainPrefix": "br33z3ap10",
25+
"http": {
26+
"method": "POST",
27+
"path": "/products",
28+
"protocol": "HTTP/1.1",
29+
"sourceIp": "140.228.54.79",
30+
"userAgent": "PostmanRuntime/7.31.0"
31+
},
32+
"requestId": "Az6r9ijSDoEEJdQ=",
33+
"stage": "$default",
34+
"time": "23/Feb/2023:21:17:25 +0000",
35+
"timeEpoch": 1677187045849
36+
},
37+
"routeKey": "POST /products",
38+
"version": "2.0"
39+
}

0 commit comments

Comments
 (0)