Skip to content

Commit 292e8f1

Browse files
author
Andrea Scuderi
committed
Improve Documentation
1 parent 48a61d4 commit 292e8f1

16 files changed

+284
-7
lines changed

Sources/BreezeDynamoDBService/BreezeCodable.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,17 @@ import FoundationEssentials
1818
import Foundation
1919
#endif
2020

21+
/// CodableSendable is a protocol that combines Sendable and Codable.
2122
public protocol CodableSendable: Sendable, Codable { }
2223

24+
/// BreezeCodable is a protocol that extends CodableSendable to include properties
25+
/// for a key, creation date, and update date.
26+
/// It is designed to be used with Breeze services that require these common fields
27+
/// for items stored in a database, such as DynamoDB.
28+
/// - Parameters:
29+
/// - key: A unique identifier for the item.
30+
/// - createdAt: An optional string representing the creation date of the item.
31+
/// - updatedAt: An optional string representing the last update date of the item.
2332
public protocol BreezeCodable: CodableSendable {
2433
var key: String { get set }
2534
var createdAt: String? { get set }

Sources/BreezeDynamoDBService/BreezeDynamoDBConfig.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,16 @@
1414

1515
import SotoCore
1616

17+
/// BreezeDynamoDBConfig is a configuration structure for Breeze DynamoDB service.
18+
/// It contains the necessary parameters to connect to a DynamoDB instance, including the region, table name, key name, and an optional endpoint.
1719
public struct BreezeDynamoDBConfig: Sendable {
20+
21+
/// Initializes a new instance of BreezeDynamoDBConfig.
22+
/// - Parameters:
23+
/// - region: The AWS region where the DynamoDB table is located.
24+
/// - tableName: The name of the DynamoDB table.
25+
/// - keyName: The name of the primary key in the DynamoDB table.
26+
/// - endpoint: An optional endpoint URL for the DynamoDB service. If not provided, the default AWS endpoint will be used.
1827
public init(
1928
region: Region,
2029
tableName: String,
@@ -27,8 +36,15 @@ public struct BreezeDynamoDBConfig: Sendable {
2736
self.endpoint = endpoint
2837
}
2938

39+
/// The AWS region where the DynamoDB table is located.
3040
public let region: Region
41+
42+
/// The name of the DynamoDB table.
3143
public let tableName: String
44+
45+
/// The name of the primary key in the DynamoDB table.
3246
public let keyName: String
47+
48+
/// An optional endpoint URL for the DynamoDB service.
3349
public let endpoint: String?
3450
}

Sources/BreezeDynamoDBService/BreezeDynamoDBManager.swift

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,32 @@ import struct Foundation.Date
1616
import NIO
1717
import SotoDynamoDB
1818

19+
/// BreezeDynamoDBManager is a manager for handling DynamoDB operations in Breeze.
20+
/// It provides methods to create, read, update, delete, and list items in a DynamoDB table.
21+
/// It conforms to the BreezeDynamoDBManaging protocol, which defines the necessary operations for Breeze's DynamoDB integration.
22+
/// - Note: This manager requires a DynamoDB instance, a table name, and a key name to operate.
23+
/// It uses the SotoDynamoDB library to interact with AWS DynamoDB services.
1924
public struct BreezeDynamoDBManager: BreezeDynamoDBManaging {
25+
26+
/// ServiceError defines the possible errors that can occur when interacting with the BreezeDynamoDBManager.
2027
enum ServiceError: Error {
28+
/// Indicates that the requested item was not found in the DynamoDB table.
2129
case notFound
30+
/// Indicates that the operation failed due to missing parameters, such as a required key.
2231
case missingParameters
2332
}
24-
25-
let db: DynamoDB
33+
34+
/// The name of the primary key in the DynamoDB table.
2635
public let keyName: String
36+
37+
let db: DynamoDB
2738
let tableName: String
2839

40+
/// Initializes a new instance of BreezeDynamoDBManager.
41+
/// - Parameters:
42+
/// - db: The DynamoDB instance to use for operations.
43+
/// - tableName: The name of the DynamoDB table to manage.
44+
/// - keyName: The name of the primary key in the DynamoDB table.
2945
public init(db: DynamoDB, tableName: String, keyName: String) {
3046
self.db = db
3147
self.tableName = tableName
@@ -34,6 +50,10 @@ public struct BreezeDynamoDBManager: BreezeDynamoDBManaging {
3450
}
3551

3652
public extension BreezeDynamoDBManager {
53+
54+
/// Creates a new item in the DynamoDB table.
55+
/// - Parameter item: The item to create, conforming to the BreezeCodable protocol.
56+
/// - Returns: The created item, with its `createdAt` and `updatedAt` timestamps set.
3757
func createItem<T: BreezeCodable>(item: T) async throws -> T {
3858
var item = item
3959
let date = Date()
@@ -49,6 +69,9 @@ public extension BreezeDynamoDBManager {
4969
return try await readItem(key: item.key)
5070
}
5171

72+
/// Reads an item from the DynamoDB table by its key.
73+
/// - Parameter key: The key of the item to read.
74+
/// - Returns: The item with the specified key, conforming to the BreezeCodable protocol.
5275
func readItem<T: BreezeCodable>(key: String) async throws -> T {
5376
let input = DynamoDB.GetItemInput(
5477
key: [keyName: DynamoDB.AttributeValue.s(key)],
@@ -65,6 +88,11 @@ public extension BreezeDynamoDBManager {
6588
let oldUpdatedAt: String
6689
}
6790

91+
/// Updates an existing item in the DynamoDB table.
92+
/// - Parameter item: The item to update, conforming to the BreezeCodable protocol.
93+
/// - Returns: The updated item, with its `updatedAt` timestamp set to the current date.
94+
/// - Throws: An error if the item cannot be updated, such as if the item does not exist or the condition fails.
95+
/// - Important: The update operation checks that the `updatedAt` and `createdAt` timestamps match the existing values to prevent concurrent modifications.
6896
func updateItem<T: BreezeCodable>(item: T) async throws -> T {
6997
var item = item
7098
let oldUpdatedAt = item.updatedAt ?? ""
@@ -82,6 +110,10 @@ public extension BreezeDynamoDBManager {
82110
return try await readItem(key: item.key)
83111
}
84112

113+
/// Deletes an item from the DynamoDB table.
114+
/// - Parameter item: The item to delete, conforming to the BreezeCodable protocol.
115+
/// - Throws: An error if the item cannot be deleted, such as if the item does not exist or the condition fails.
116+
/// - Important: The `updatedAt` and `createdAt` timestamps must be set on the item to ensure safe deletion. This method checks that the `updatedAt` and `createdAt` timestamps match the existing values to prevent concurrent modifications.
85117
func deleteItem<T: BreezeCodable>(item: T) async throws {
86118
guard let updatedAt = item.updatedAt,
87119
let createdAt = item.createdAt else {
@@ -101,6 +133,13 @@ public extension BreezeDynamoDBManager {
101133
return
102134
}
103135

136+
/// Lists items in the DynamoDB table with optional pagination.
137+
/// - Parameters:
138+
/// - key: An optional key to start the listing from, useful for pagination.
139+
/// - limit: An optional limit on the number of items to return.
140+
/// - Returns: A `ListResponse` containing the items and the last evaluated key for pagination.
141+
/// - Throws: An error if the listing operation fails.
142+
/// - Important: The `key` parameter is used to continue listing from a specific point, and the `limit` parameter controls how many items are returned in one call.
104143
func listItems<T: BreezeCodable>(key: String?, limit: Int?) async throws -> ListResponse<T> {
105144
var exclusiveStartKey: [String: DynamoDB.AttributeValue]?
106145
if let key {

Sources/BreezeDynamoDBService/BreezeDynamoDBManaging.swift

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,60 @@
1414

1515
import SotoDynamoDB
1616

17+
/// BreezeDynamoDBManaging is a protocol that defines the methods for managing DynamoDB items.
1718
public protocol BreezeDynamoDBManaging: Sendable {
19+
/// The keyName is the name of the primary key in the DynamoDB table.
1820
var keyName: String { get }
21+
/// Initializes the BreezeDynamoDBManaging with the provided DynamoDB client, table name, and key name.
22+
/// - Parameters:
23+
/// - db: The DynamoDB client to use for database operations.
24+
/// - tableName: The name of the DynamoDB table.
25+
/// - keyName: The name of the primary key in the DynamoDB table.
1926
init(db: DynamoDB, tableName: String, keyName: String)
27+
28+
/// Creates a new item in the DynamoDB table.
29+
/// - Parameter item: The item to create, conforming to BreezeCodable.
30+
/// - Returns: The created item.
31+
/// - Note:
32+
/// - The item must conform to BreezeCodable.
2033
func createItem<Item: BreezeCodable>(item: Item) async throws -> Item
34+
35+
/// Reads an item from the DynamoDB table.
36+
/// - Parameter key: The key of the item to read.
37+
/// - Returns: The item read from the table, conforming to BreezeCodable.
38+
/// - Throws: An error if the item could not be read.
39+
/// - Note:
40+
/// - The key should match the primary key defined in the DynamoDB table.
41+
/// - The item must conform to BreezeCodable.
2142
func readItem<Item: BreezeCodable>(key: String) async throws -> Item
43+
44+
/// Updates an existing item in the DynamoDB table.
45+
/// - Parameter item: The item to update, conforming to BreezeCodable.
46+
/// - Returns: The updated item.
47+
/// - Throws: An error if the item could not be updated.
48+
/// - Note:
49+
/// - The item must have the same primary key as an existing item in the table.
50+
/// - The item must conform to BreezeCodable.
2251
func updateItem<Item: BreezeCodable>(item: Item) async throws -> Item
52+
53+
/// Deletes an item from the DynamoDB table.
54+
/// - Parameter item: The item to delete, conforming to BreezeCodable.
55+
/// - Throws: An error if the item could not be deleted.
56+
/// - Returns: Void if the item was successfully deleted.
57+
/// - Note:
58+
/// - The item must conform to BreezeCodable.
59+
/// - The item must have the same primary key as an existing item in the table.
2360
func deleteItem<Item: BreezeCodable>(item: Item) async throws
61+
62+
/// Lists items in the DynamoDB table.
63+
/// - Parameters:
64+
/// - key: An optional key to filter the items.
65+
/// - limit: An optional limit on the number of items to return.
66+
/// - Returns: A ListResponse containing the items and an optional last evaluated key.
67+
/// - Throws: An error if the items could not be listed.
68+
/// - Note:
69+
/// - The items must conform to BreezeCodable.
70+
/// - The key is used to filter the items based on the primary key defined in the DynamoDB table.
71+
/// - The limit is used to control the number of items returned in the response.
2472
func listItems<Item: BreezeCodable>(key: String?, limit: Int?) async throws -> ListResponse<Item>
2573
}

Sources/BreezeDynamoDBService/BreezeDynamoDBService.swift

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ import AsyncHTTPClient
1717
import ServiceLifecycle
1818
import Logging
1919

20+
/// BreezeDynamoDBServing
21+
/// A protocol that defines the interface for a Breeze DynamoDB service.
22+
/// It provides methods to access the database manager and to gracefully shutdown the service.
2023
public protocol BreezeDynamoDBServing: Actor {
2124
func dbManager() async -> BreezeDynamoDBManaging
2225
func gracefulShutdown() throws
@@ -26,9 +29,17 @@ public actor BreezeDynamoDBService: BreezeDynamoDBServing {
2629

2730
private let dbManager: BreezeDynamoDBManaging
2831
private let logger: Logger
29-
private var awsClient: AWSClient
32+
private let awsClient: AWSClient
3033
private let httpClient: HTTPClient
34+
private var isShutdown = false
3135

36+
/// Initializes the BreezeDynamoDBService with the provided configuration.
37+
/// - Parameters:
38+
/// - config: The configuration for the DynamoDB service.
39+
/// - httpConfig: The configuration for the HTTP client.
40+
/// - logger: The logger to use for logging messages.
41+
/// - DBManagingType: The type of the BreezeDynamoDBManaging to use. Defaults to BreezeDynamoDBManager.
42+
/// This initializer sets up the AWS client, HTTP client, and the database manager.
3243
public init(
3344
config: BreezeDynamoDBConfig,
3445
httpConfig: BreezeHTTPClientConfig,
@@ -64,18 +75,27 @@ public actor BreezeDynamoDBService: BreezeDynamoDBServing {
6475
logger.info("DBManager is ready.")
6576
}
6677

78+
/// Returns the BreezeDynamoDBManaging instance.
6779
public func dbManager() async -> BreezeDynamoDBManaging {
6880
logger.info("Starting DynamoDBService...")
6981
return self.dbManager
7082
}
7183

84+
/// Gracefully shutdown the service and its components.
85+
/// - Throws: An error if the shutdown process fails.
86+
/// This method ensures that the AWS client and HTTP client are properly shutdown before marking the service as shutdown.
87+
/// It also logs the shutdown process.
88+
/// This method is idempotent;
89+
/// - Important: This method must be called at leat once to ensure that resources are released properly. If the method is not called, it will lead to a crash.
7290
public func gracefulShutdown() throws {
91+
guard !isShutdown else { return }
7392
logger.info("Stopping DynamoDBService...")
7493
try awsClient.syncShutdown()
7594
logger.info("DynamoDBService is stopped.")
7695
logger.info("Stopping HTTPClient...")
7796
try httpClient.syncShutdown()
7897
logger.info("HTTPClient is stopped.")
98+
isShutdown = true
7999
}
80100
}
81101

Sources/BreezeDynamoDBService/BreezeHTTPClientConfig.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,26 @@
1515
import Logging
1616
import NIOCore
1717

18+
/// BreezeClientServiceError defines the errors that can occur in the Breeze Client Service.
1819
public enum BreezeClientServiceError: Error {
1920
case invalidHttpClient
2021
}
2122

23+
/// BreezeHTTPClientConfig is a configuration structure for the Breeze HTTP client.
2224
public struct BreezeHTTPClientConfig: Sendable {
25+
26+
/// Initializes a new instance of BreezeHTTPClientConfig.
27+
/// - Parameters:
28+
/// - timeout: The timeout duration for HTTP requests.
29+
/// - logger: The logger to use for logging messages.
2330
public init(timeout: TimeAmount, logger: Logger) {
2431
self.timeout = timeout
2532
self.logger = logger
2633
}
2734

35+
/// The timeout duration for HTTP requests.
2836
public let timeout: TimeAmount
37+
38+
/// The logger to use for logging messages.
2939
public let logger: Logger
3040
}

Sources/BreezeDynamoDBService/Foundation+Extension.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import class Foundation.DateFormatter
1616
import struct Foundation.Date
1717
import struct Foundation.TimeZone
1818

19+
/// This file contains extensions for DateFormatter, Date, and String to handle ISO 8601 date formatting and parsing.
20+
/// These extensions provide a convenient way to convert between `Date` objects and their ISO 8601 string representations.
1921
extension DateFormatter {
2022
static var iso8061: DateFormatter {
2123
let formatter = DateFormatter()
@@ -26,13 +28,15 @@ extension DateFormatter {
2628
}
2729

2830
extension Date {
31+
/// Returns a string representation of the date in ISO 8601 format.
2932
var iso8601: String {
3033
let formatter = DateFormatter.iso8061
3134
return formatter.string(from: self)
3235
}
3336
}
3437

3538
extension String {
39+
/// Attempts to parse the string as an ISO 8601 date.
3640
var iso8601: Date? {
3741
let formatter = DateFormatter.iso8061
3842
return formatter.date(from: self)

Sources/BreezeDynamoDBService/ListResponse.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,25 @@ import FoundationEssentials
1818
import Foundation
1919
#endif
2020

21+
/// Model representing a paginated list response from a DynamoDB operation.
22+
/// This struct contains an array of items and an optional last evaluated key for pagination.
23+
/// This struct conforms to `CodableSendable`, allowing it to be encoded and decoded for network transmission or storage.
2124
public struct ListResponse<Item: CodableSendable>: CodableSendable {
25+
26+
/// Initializes a new instance of `ListResponse`.
27+
/// - Parameters:
28+
/// - items: An array of items returned from the DynamoDB operation.
29+
/// - lastEvaluatedKey: An optional string representing the last evaluated key for pagination. If nil, it indicates that there are no more items to fetch.
30+
///
31+
/// This initializer is used to create a paginated response for DynamoDB operations.
2232
public init(items: [Item], lastEvaluatedKey: String? = nil) {
2333
self.items = items
2434
self.lastEvaluatedKey = lastEvaluatedKey
2535
}
36+
37+
/// The items returned from the DynamoDB operation.
2638
public let items: [Item]
39+
40+
/// An optional string representing the last evaluated key for pagination.
2741
public let lastEvaluatedKey: String?
2842
}

Sources/BreezeLambdaAPI/APIGatewayV2Response+Extensions.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ import class Foundation.JSONEncoder
1919
extension APIGatewayV2Response {
2020
private static let encoder = JSONEncoder()
2121

22-
/// defaultHeaders
2322
/// Override the headers in APIGatewayV2Response
2423
static let defaultHeaders = [ "Content-Type": "application/json" ]
2524

25+
/// A model representing the body of an error response
2626
struct BodyError: Codable {
2727
let error: String
2828
}
2929

30-
/// init
30+
/// Initializer for APIGatewayV2Response with a BodyError
3131
/// - Parameters:
3232
/// - error: Error
3333
/// - statusCode: HTTP Status Code
@@ -36,7 +36,7 @@ extension APIGatewayV2Response {
3636
self.init(with: bodyError, statusCode: statusCode)
3737
}
3838

39-
/// init
39+
/// Initializer for APIGatewayV2Response with an Encodable object
4040
/// - Parameters:
4141
/// - object: Encodable Object
4242
/// - statusCode: HTTP Status Code

0 commit comments

Comments
 (0)