Skip to content

Commit 8b6569e

Browse files
committed
separate protocol for simpler lambda (no init)
1 parent 2ed058b commit 8b6569e

File tree

12 files changed

+84
-77
lines changed

12 files changed

+84
-77
lines changed

Examples/Deployment/Sources/HelloWorld/HelloWorldHandler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import AWSLambdaRuntime
1616

1717
// introductory example, the obligatory "hello, world!"
1818
@main
19-
struct HelloWorldHandler: LambdaHandler {
19+
struct HelloWorldHandler: SimpleLambdaHandler {
2020
func handle(_ event: String, context: LambdaContext) async throws -> String {
2121
"hello, world"
2222
}

Examples/Echo/Lambda.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import AWSLambdaRuntime
1717
// in this example we are receiving and responding with strings
1818

1919
@main
20-
struct MyLambda: LambdaHandler {
20+
struct MyLambda: SimpleLambdaHandler {
2121
func handle(_ input: String, context: LambdaContext) async throws -> String {
2222
// as an example, respond with the input's reversed
2323
String(input.reversed())

Examples/ErrorHandling/Lambda.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import AWSLambdaRuntime
1717
// MARK: - Run Lambda
1818

1919
@main
20-
struct MyLambda: LambdaHandler {
20+
struct MyLambda: SimpleLambdaHandler {
2121
typealias Event = Request
2222
typealias Output = Response
2323

Examples/JSON/Lambda.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct Response: Codable {
2626
// codables to model your request and response objects
2727

2828
@main
29-
struct MyLambda: LambdaHandler {
29+
struct MyLambda: SimpleLambdaHandler {
3030
typealias Event = Request
3131
typealias Output = Response
3232

Examples/LocalDebugging/MyLambda/Lambda.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import Shared
1919
// a local server simulator which will allow local debugging
2020

2121
@main
22-
struct MyLambda: LambdaHandler {
22+
struct MyLambda: SimpleLambdaHandler {
2323
typealias Event = Request
2424
typealias Output = Response
2525

Examples/Testing/Sources/Lambda.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import AWSLambdaRuntime
1717
// in this example we are receiving and responding with strings
1818

1919
@main
20-
struct MyLambda: LambdaHandler {
20+
struct MyLambda: SimpleLambdaHandler {
2121
func handle(_ event: String, context: LambdaContext) async throws -> String {
2222
// as an example, respond with the event's reversed body
2323
String(event.reversed())

Sources/AWSLambdaRuntimeCore/Lambda+String.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import NIOCore
1919
extension LambdaHandler where Event == String {
2020
/// Implementation of a `ByteBuffer` to `String` decoding.
2121
@inlinable
22-
public func decode(buffer: ByteBuffer) throws -> String {
22+
public func decode(buffer: ByteBuffer) throws -> Event {
2323
guard let value = buffer.getString(at: buffer.readerIndex, length: buffer.readableBytes) else {
2424
throw CodecError.invalidString
2525
}
@@ -31,7 +31,7 @@ extension LambdaHandler where Event == String {
3131
extension LambdaHandler where Output == String {
3232
/// Implementation of `String` to `ByteBuffer` encoding.
3333
@inlinable
34-
public func encode(value: String, into buffer: inout ByteBuffer) throws {
34+
public func encode(value: Output, into buffer: inout ByteBuffer) throws {
3535
buffer.writeString(value)
3636
}
3737
}
@@ -41,7 +41,7 @@ extension LambdaHandler where Output == String {
4141
extension EventLoopLambdaHandler where Event == String {
4242
/// Implementation of `String` to `ByteBuffer` encoding.
4343
@inlinable
44-
public func decode(buffer: ByteBuffer) throws -> String {
44+
public func decode(buffer: ByteBuffer) throws -> Event {
4545
guard let value = buffer.getString(at: buffer.readerIndex, length: buffer.readableBytes) else {
4646
throw CodecError.invalidString
4747
}
@@ -52,7 +52,7 @@ extension EventLoopLambdaHandler where Event == String {
5252
extension EventLoopLambdaHandler where Output == String {
5353
/// Implementation of a `ByteBuffer` to `String` decoding.
5454
@inlinable
55-
public func encode(value: String, into buffer: inout ByteBuffer) throws {
55+
public func encode(value: Output, into buffer: inout ByteBuffer) throws {
5656
buffer.writeString(value)
5757
}
5858
}

Sources/AWSLambdaRuntimeCore/LambdaHandler.swift

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,31 @@
1515
import Dispatch
1616
import NIOCore
1717

18+
// MARK: - SimpleLambdaHandler
19+
20+
/// Strongly typed, processing protocol for a Lambda that takes a user defined
21+
/// ``LambdaHandler/Event`` and returns a user defined
22+
/// ``LambdaHandler/Output`` asynchronously.
23+
///
24+
/// - note: Most users should implement the ``LambdaHandler`` protocol instead
25+
/// which defines the Lambda initialization method.
26+
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
27+
public protocol SimpleLambdaHandler: LambdaHandler {
28+
init()
29+
}
30+
31+
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
32+
extension SimpleLambdaHandler {
33+
public init(context: LambdaInitializationContext) async throws {
34+
self.init()
35+
}
36+
}
37+
1838
// MARK: - LambdaHandler
1939

2040
/// Strongly typed, processing protocol for a Lambda that takes a user defined
21-
/// ``EventLoopLambdaHandler/Event`` and returns a user defined
22-
/// ``EventLoopLambdaHandler/Output`` asynchronously.
41+
/// ``LambdaHandler/Event`` and returns a user defined
42+
/// ``LambdaHandler/Output`` asynchronously.
2343
///
2444
/// - note: Most users should implement this protocol instead of the lower
2545
/// level protocols ``EventLoopLambdaHandler`` and
@@ -33,8 +53,12 @@ public protocol LambdaHandler {
3353
/// The lambda function's output. Can be `Void`.
3454
associatedtype Output
3555

36-
init()
37-
56+
/// The Lambda initialization method.
57+
/// Use this method to initialize resources that will be used in every request.
58+
///
59+
/// Examples for this can be HTTP or database clients.
60+
/// - parameters:
61+
/// - context: Runtime ``LambdaInitializationContext``.
3862
init(context: LambdaInitializationContext) async throws
3963

4064
/// The Lambda handling method.
@@ -66,23 +90,6 @@ public protocol LambdaHandler {
6690
func decode(buffer: ByteBuffer) throws -> Event
6791
}
6892

69-
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
70-
extension LambdaHandler {
71-
public init() {
72-
self.init()
73-
}
74-
75-
/// The Lambda initialization method.
76-
/// Use this method to initialize resources that will be used in every request.
77-
///
78-
/// Examples for this can be HTTP or database clients.
79-
/// - parameters:
80-
/// - context: Runtime ``LambdaInitializationContext``.
81-
public init(context: LambdaInitializationContext) async throws {
82-
self.init()
83-
}
84-
}
85-
8693
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
8794
final class CodableLambdaHandler<Underlying: LambdaHandler>: ByteBufferLambdaHandler {
8895
private let handler: Underlying
@@ -133,7 +140,7 @@ final class CodableLambdaHandler<Underlying: LambdaHandler>: ByteBufferLambdaHan
133140
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
134141
extension LambdaHandler where Output == Void {
135142
@inlinable
136-
public func encode(value: Void, into buffer: inout ByteBuffer) throws {}
143+
public func encode(value: Output, into buffer: inout ByteBuffer) throws {}
137144
}
138145

139146
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
@@ -173,10 +180,7 @@ internal struct UncheckedSendableHandler<Underlying: LambdaHandler, Event, Outpu
173180
// MARK: - EventLoopLambdaHandler
174181

175182
/// Strongly typed, `EventLoopFuture` based processing protocol for a Lambda that takes a user
176-
/// defined ``Event`` and returns a user defined ``Output`` asynchronously.
177-
///
178-
/// ``EventLoopLambdaHandler`` extends ``ByteBufferLambdaHandler``, performing
179-
/// `ByteBuffer` -> ``Event`` decoding and ``Output`` -> `ByteBuffer` encoding.
183+
/// defined ``EventLoopLambdaHandler/Event`` and returns a user defined ``EventLoopLambdaHandler/Output`` asynchronously.
180184
///
181185
/// - note: To implement a Lambda, implement either ``LambdaHandler`` or the
182186
/// ``EventLoopLambdaHandler`` protocol. The ``LambdaHandler`` will offload
@@ -235,7 +239,7 @@ public protocol EventLoopLambdaHandler {
235239
/// Implementation of `ByteBuffer` to `Void` decoding.
236240
extension EventLoopLambdaHandler where Output == Void {
237241
@inlinable
238-
public func encode(value: Void, into buffer: inout ByteBuffer) throws {}
242+
public func encode(value: Output, into buffer: inout ByteBuffer) throws {}
239243
}
240244

241245
internal final class CodableEventLoopLambdaHandler<Underlying: EventLoopLambdaHandler>: ByteBufferLambdaHandler {

Tests/AWSLambdaRuntimeCoreTests/LambdaHandlerTest.swift

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,15 @@ import NIOCore
1717
import XCTest
1818

1919
class LambdaHandlerTest: XCTestCase {
20-
// MARK: - LambdaHandler
20+
// MARK: - SimpleLambdaHandler
2121

2222
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
23-
func testBootstrapSuccess() {
23+
func testBootstrapSimpleNoInit() {
2424
let server = MockLambdaServer(behavior: Behavior())
2525
XCTAssertNoThrow(try server.start().wait())
2626
defer { XCTAssertNoThrow(try server.stop().wait()) }
2727

28-
struct TestBootstrapHandler: LambdaHandler {
29-
var initialized = false
30-
31-
init(context: LambdaInitializationContext) async throws {
32-
XCTAssertFalse(self.initialized)
33-
try await Task.sleep(nanoseconds: 100 * 1000 * 1000) // 0.1 seconds
34-
self.initialized = true
35-
}
36-
28+
struct TestBootstrapHandler: SimpleLambdaHandler {
3729
func handle(_ event: String, context: LambdaContext) async throws -> String {
3830
event
3931
}
@@ -46,45 +38,44 @@ class LambdaHandlerTest: XCTestCase {
4638
}
4739

4840
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
49-
func testBootstrapFailure() {
50-
let server = MockLambdaServer(behavior: FailedBootstrapBehavior())
41+
func testBootstrapSimpleInit() {
42+
let server = MockLambdaServer(behavior: Behavior())
5143
XCTAssertNoThrow(try server.start().wait())
5244
defer { XCTAssertNoThrow(try server.stop().wait()) }
5345

54-
struct TestBootstrapHandler: LambdaHandler {
55-
typealias Event = String
56-
typealias Output = Void
57-
46+
struct TestBootstrapHandler: SimpleLambdaHandler {
5847
var initialized = false
5948

60-
init(context: LambdaInitializationContext) async throws {
49+
init() {
6150
XCTAssertFalse(self.initialized)
62-
try await Task.sleep(nanoseconds: 100 * 1000 * 1000) // 0.1 seconds
63-
throw TestError("kaboom")
51+
self.initialized = true
6452
}
6553

66-
func handle(_ event: String, context: LambdaContext) async throws {
67-
XCTFail("How can this be called if init failed")
54+
func handle(_ event: String, context: LambdaContext) async throws -> String {
55+
event
6856
}
6957
}
7058

7159
let maxTimes = Int.random(in: 10 ... 20)
7260
let configuration = LambdaConfiguration(lifecycle: .init(maxTimes: maxTimes))
7361
let result = Lambda.run(configuration: configuration, handlerType: TestBootstrapHandler.self)
74-
assertLambdaRuntimeResult(result, shouldFailWithError: TestError("kaboom"))
62+
assertLambdaRuntimeResult(result, shouldHaveRun: maxTimes)
7563
}
7664

65+
// MARK: - LambdaHandler
66+
7767
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
78-
func testBootstrapInitSimple() {
68+
func testBootstrapSuccess() {
7969
let server = MockLambdaServer(behavior: Behavior())
8070
XCTAssertNoThrow(try server.start().wait())
8171
defer { XCTAssertNoThrow(try server.stop().wait()) }
8272

8373
struct TestBootstrapHandler: LambdaHandler {
8474
var initialized = false
8575

86-
init() {
76+
init(context: LambdaInitializationContext) async throws {
8777
XCTAssertFalse(self.initialized)
78+
try await Task.sleep(nanoseconds: 100 * 1000 * 1000) // 0.1 seconds
8879
self.initialized = true
8980
}
9081

@@ -100,21 +91,32 @@ class LambdaHandlerTest: XCTestCase {
10091
}
10192

10293
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
103-
func testBootstrapNoInit() {
104-
let server = MockLambdaServer(behavior: Behavior())
94+
func testBootstrapFailure() {
95+
let server = MockLambdaServer(behavior: FailedBootstrapBehavior())
10596
XCTAssertNoThrow(try server.start().wait())
10697
defer { XCTAssertNoThrow(try server.stop().wait()) }
10798

10899
struct TestBootstrapHandler: LambdaHandler {
109-
func handle(_ event: String, context: LambdaContext) async throws -> String {
110-
event
100+
typealias Event = String
101+
typealias Output = Void
102+
103+
var initialized = false
104+
105+
init(context: LambdaInitializationContext) async throws {
106+
XCTAssertFalse(self.initialized)
107+
try await Task.sleep(nanoseconds: 100 * 1000 * 1000) // 0.1 seconds
108+
throw TestError("kaboom")
109+
}
110+
111+
func handle(_ event: String, context: LambdaContext) async throws {
112+
XCTFail("How can this be called if init failed")
111113
}
112114
}
113115

114116
let maxTimes = Int.random(in: 10 ... 20)
115117
let configuration = LambdaConfiguration(lifecycle: .init(maxTimes: maxTimes))
116118
let result = Lambda.run(configuration: configuration, handlerType: TestBootstrapHandler.self)
117-
assertLambdaRuntimeResult(result, shouldHaveRun: maxTimes)
119+
assertLambdaRuntimeResult(result, shouldFailWithError: TestError("kaboom"))
118120
}
119121

120122
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
@@ -123,7 +125,7 @@ class LambdaHandlerTest: XCTestCase {
123125
XCTAssertNoThrow(try server.start().wait())
124126
defer { XCTAssertNoThrow(try server.stop().wait()) }
125127

126-
struct Handler: LambdaHandler {
128+
struct Handler: SimpleLambdaHandler {
127129
func handle(_ event: String, context: LambdaContext) async throws -> String {
128130
event
129131
}
@@ -141,7 +143,7 @@ class LambdaHandlerTest: XCTestCase {
141143
XCTAssertNoThrow(try server.start().wait())
142144
defer { XCTAssertNoThrow(try server.stop().wait()) }
143145

144-
struct Handler: LambdaHandler {
146+
struct Handler: SimpleLambdaHandler {
145147
func handle(_ event: String, context: LambdaContext) async throws {}
146148
}
147149

@@ -158,7 +160,7 @@ class LambdaHandlerTest: XCTestCase {
158160
XCTAssertNoThrow(try server.start().wait())
159161
defer { XCTAssertNoThrow(try server.stop().wait()) }
160162

161-
struct Handler: LambdaHandler {
163+
struct Handler: SimpleLambdaHandler {
162164
func handle(_ event: String, context: LambdaContext) async throws -> String {
163165
throw TestError("boom")
164166
}

Tests/AWSLambdaRuntimeTests/Lambda+CodableTest.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class CodableLambdaTest: XCTestCase {
100100

101101
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
102102
func testCodableVoidHandler() async throws {
103-
struct Handler: LambdaHandler {
103+
struct Handler: SimpleLambdaHandler {
104104
typealias Event = Request
105105
typealias Output = Void
106106

@@ -130,7 +130,7 @@ class CodableLambdaTest: XCTestCase {
130130

131131
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
132132
func testCodableHandler() async throws {
133-
struct Handler: LambdaHandler {
133+
struct Handler: SimpleLambdaHandler {
134134
typealias Event = Request
135135
typealias Output = Response
136136

0 commit comments

Comments
 (0)