diff --git a/.gitignore b/.gitignore index 04708b0f..000f5669 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ xcuserdata Package.resolved .serverless +.vscode diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Documentation.md b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Documentation.md new file mode 100644 index 00000000..68088df8 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Documentation.md @@ -0,0 +1,24 @@ +# ``AWSLambdaRuntimeCore`` + +An AWS Lambda runtime for the Swift programming language + +## Overview + +Many modern systems have client components like iOS, macOS or watchOS applications as well as server components that those clients interact with. Serverless functions are often the easiest and most efficient way for client application developers to extend their applications into the cloud. + +Serverless functions are increasingly becoming a popular choice for running event-driven or otherwise ad-hoc compute tasks in the cloud. They power mission critical microservices and data intensive workloads. In many cases, serverless functions allow developers to more easily scale and control compute costs given their on-demand nature. + +When using serverless functions, attention must be given to resource utilization as it directly impacts the costs of the system. This is where Swift shines! With its low memory footprint, deterministic performance, and quick start time, Swift is a fantastic match for the serverless functions architecture. + +Combine this with Swift's developer friendliness, expressiveness, and emphasis on safety, and we have a solution that is great for developers at all skill levels, scalable, and cost effective. + +Swift AWS Lambda Runtime was designed to make building Lambda functions in Swift simple and safe. The library is an implementation of the [AWS Lambda Runtime API](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html) and uses an embedded asynchronous HTTP client based on [SwiftNIO](https://github.com/apple/swift-nio) that is fine-tuned for performance in the AWS Lambda Runtime context. The library provides a multi-tier API that allows building a range of Lambda functions: from quick and simple closures to complex, performance-sensitive event handlers. + +## Topics + +### Essentials + +- +- + - ``LambdaHandler`` + diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-01-01-package-init.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-01-01-package-init.sh new file mode 100644 index 00000000..a54719a3 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-01-01-package-init.sh @@ -0,0 +1,2 @@ +# Create a project directory +mkdir SquareNumber && cd SquareNumber \ No newline at end of file diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-01-02-package-init.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-01-02-package-init.sh new file mode 100644 index 00000000..a96b825c --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-01-02-package-init.sh @@ -0,0 +1,4 @@ +# Create a project directory +mkdir SquareNumber && cd SquareNumber +# create a skeleton project +swift package init --type executable \ No newline at end of file diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-01-03-package-init.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-01-03-package-init.sh new file mode 100644 index 00000000..aa6e4926 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-01-03-package-init.sh @@ -0,0 +1,6 @@ +# Create a project directory +mkdir SquareNumber && cd SquareNumber +# create a skeleton project +swift package init --type executable +# open Xcode in the current directory +xed . \ No newline at end of file diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-01-04-package-init.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-01-04-package-init.sh new file mode 100644 index 00000000..fc946011 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-01-04-package-init.sh @@ -0,0 +1,8 @@ +# Create a project directory +mkdir SquareNumber && cd SquareNumber +# create a skeleton project +swift package init --type executable +# open Xcode in the current directory +xed . +# alternatively, you may open VSCode +code . \ No newline at end of file diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-01-package.swift b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-01-package.swift new file mode 100644 index 00000000..dada42b4 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-01-package.swift @@ -0,0 +1,8 @@ +// swift-tools-version:5.8 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "SquareNumberLambda", +) diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-02-package.swift b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-02-package.swift new file mode 100644 index 00000000..40b9f784 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-02-package.swift @@ -0,0 +1,11 @@ +// swift-tools-version:5.8 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "SquareNumberLambda", + platforms: [ + .macOS(.v12), + ], +) diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-03-package.swift b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-03-package.swift new file mode 100644 index 00000000..88258ed8 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-03-package.swift @@ -0,0 +1,14 @@ +// swift-tools-version:5.8 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "SquareNumberLambda", + platforms: [ + .macOS(.v12), + ], + dependencies: [ + .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "1.0.0-alpha"), + ], +) diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-04-package.swift b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-04-package.swift new file mode 100644 index 00000000..b1d69ed5 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-04-package.swift @@ -0,0 +1,17 @@ +// swift-tools-version:5.8 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "SquareNumberLambda", + platforms: [ + .macOS(.v12), + ], + products: [ + .executable(name: "SquareNumberLambda", targets: ["SquareNumberLambda"]), + ], + dependencies: [ + .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "1.0.0-alpha"), + ], +) diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-05-package.swift b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-05-package.swift new file mode 100644 index 00000000..bd9f7290 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-02-05-package.swift @@ -0,0 +1,26 @@ +// swift-tools-version:5.8 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "SquareNumberLambda", + platforms: [ + .macOS(.v12), + ], + products: [ + .executable(name: "SquareNumberLambda", targets: ["SquareNumberLambda"]), + ], + dependencies: [ + .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "1.0.0-alpha"), + ], + targets: [ + .executableTarget( + name: "SquareNumberLambda", + dependencies: [ + .product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"), + ], + path: "." + ), + ] +) diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-01-main.swift b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-01-main.swift new file mode 100644 index 00000000..35d722a6 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-01-main.swift @@ -0,0 +1,3 @@ + +@main +struct SquareNumberHandler: SimpleLambdaHandler {} diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-02-main.swift b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-02-main.swift new file mode 100644 index 00000000..b4b0b28d --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-02-main.swift @@ -0,0 +1,4 @@ +import AWSLambdaRuntime + +@main +struct SquareNumberHandler: SimpleLambdaHandler {} diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-03-main.swift b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-03-main.swift new file mode 100644 index 00000000..bf17f189 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-03-main.swift @@ -0,0 +1,6 @@ +import AWSLambdaRuntime + +@main +struct SquareNumberHandler: SimpleLambdaHandler { + func handle(_ event: Event, context: LambdaContext) async throws -> Output {} +} diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-04-main.swift b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-04-main.swift new file mode 100644 index 00000000..6647aec0 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-04-main.swift @@ -0,0 +1,14 @@ +import AWSLambdaRuntime + +struct Input: Codable { + let number: Double +} + +struct Number: Codable { + let result: Double +} + +@main +struct SquareNumberHandler: SimpleLambdaHandler { + func handle(_ event: Event, context: LambdaContext) async throws -> Output {} +} diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-05-main.swift b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-05-main.swift new file mode 100644 index 00000000..805fb5ab --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-05-main.swift @@ -0,0 +1,17 @@ +import AWSLambdaRuntime + +struct Input: Codable { + let number: Double +} + +struct Number: Codable { + let result: Double +} + +@main +struct SquareNumberHandler: SimpleLambdaHandler { + typealias Event = Input + typealias Output = Number + + func handle(_ event: Event, context: LambdaContext) async throws -> Output {} +} diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-06-main.swift b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-06-main.swift new file mode 100644 index 00000000..a8257061 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-03-06-main.swift @@ -0,0 +1,19 @@ +import AWSLambdaRuntime + +struct Input: Codable { + let number: Double +} + +struct Number: Codable { + let result: Double +} + +@main +struct SquareNumberHandler: SimpleLambdaHandler { + typealias Event = Input + typealias Output = Number + + func handle(_ event: Event, context: LambdaContext) async throws -> Output { + Number(result: event.number * event.number) + } +} diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-03-console-output.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-03-console-output.sh new file mode 100644 index 00000000..7ba3caf2 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-03-console-output.sh @@ -0,0 +1,5 @@ +2023-04-14T11:42:21+0200 info LocalLambdaServer : [AWSLambdaRuntimeCore] LocalLambdaServer started and listening on 127.0.0.1:7000, receiving events on /invoke +2023-04-14T11:42:21+0200 info Lambda : [AWSLambdaRuntimeCore] lambda runtime starting with LambdaConfiguration + General(logLevel: info)) + Lifecycle(id: 104957691689708, maxTimes: 0, stopSignal: TERM) + RuntimeEngine(ip: 127.0.0.1, port: 7000, requestTimeout: nil diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-04-curl.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-04-curl.sh new file mode 100644 index 00000000..46dbccc0 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-04-curl.sh @@ -0,0 +1,5 @@ +curl --header "Content-Type: application/json" \ + --request POST \ + --data '{"number": 3}' \ + http://localhost:7000/invoke + diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-05-curl.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-05-curl.sh new file mode 100644 index 00000000..c5dcbe12 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-05-curl.sh @@ -0,0 +1,6 @@ +curl --header "Content-Type: application/json" \ + --request POST \ + --data '{"number": 3}' \ + http://localhost:7000/invoke + +{"result":9} diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-06-terminal.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-06-terminal.sh new file mode 100644 index 00000000..39c4f4d7 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-06-terminal.sh @@ -0,0 +1,2 @@ +export LOCAL_LAMBDA_SERVER_ENABLED=true + diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-07-terminal.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-07-terminal.sh new file mode 100644 index 00000000..f6bc5e7f --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-07-terminal.sh @@ -0,0 +1,2 @@ +export LOCAL_LAMBDA_SERVER_ENABLED=true +swift run diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-08-terminal.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-08-terminal.sh new file mode 100644 index 00000000..b1a57a88 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/03-04-08-terminal.sh @@ -0,0 +1,10 @@ +export LOCAL_LAMBDA_SERVER_ENABLED=true +swift run + +Building for debugging... +Build complete! (0.20s) +2023-04-14T10:52:25+0200 info LocalLambdaServer : [AWSLambdaRuntimeCore] LocalLambdaServer started and listening on 127.0.0.1:7000, receiving events on /invoke +2023-04-14T10:52:25+0200 info Lambda : [AWSLambdaRuntimeCore] lambda runtime starting with LambdaConfiguration + General(logLevel: info)) + Lifecycle(id: 102943961260250, maxTimes: 0, stopSignal: TERM) + RuntimeEngine(ip: 127.0.0.1, port: 7000, requestTimeout: nil diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-01-02-plugin-archive.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-01-02-plugin-archive.sh new file mode 100644 index 00000000..41e7a628 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-01-02-plugin-archive.sh @@ -0,0 +1,2 @@ +swift package --disable-sandbox plugin archive + diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-01-03-plugin-archive.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-01-03-plugin-archive.sh new file mode 100644 index 00000000..9878f478 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-01-03-plugin-archive.sh @@ -0,0 +1,19 @@ +swift package --disable-sandbox plugin archive + +------------------------------------------------------------------------- +building "squarenumberlambda" in docker +------------------------------------------------------------------------- +updating "swift:amazonlinux2" docker image + amazonlinux2: Pulling from library/swift + Digest: sha256:5b0cbe56e35210fa90365ba3a4db9cd2b284a5b74d959fc1ee56a13e9c35b378 + Status: Image is up to date for swift:amazonlinux2 + docker.io/library/swift:amazonlinux2 +building "SquareNumberLambda" + Building for production... +... +------------------------------------------------------------------------- +archiving "SquareNumberLambda" +------------------------------------------------------------------------- +1 archive created + * SquareNumberLambda at /Users/YourUserName/SquareNumberLambda/.build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/SquareNumberLambda/SquareNumberLambda.zip + diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-01-04-plugin-archive.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-01-04-plugin-archive.sh new file mode 100644 index 00000000..7652bf1c --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-01-04-plugin-archive.sh @@ -0,0 +1,21 @@ +swift package --disable-sandbox plugin archive + +------------------------------------------------------------------------- +building "squarenumberlambda" in docker +------------------------------------------------------------------------- +updating "swift:amazonlinux2" docker image + amazonlinux2: Pulling from library/swift + Digest: sha256:5b0cbe56e35210fa90365ba3a4db9cd2b284a5b74d959fc1ee56a13e9c35b378 + Status: Image is up to date for swift:amazonlinux2 + docker.io/library/swift:amazonlinux2 +building "SquareNumberLambda" + Building for production... +... +------------------------------------------------------------------------- +archiving "SquareNumberLambda" +------------------------------------------------------------------------- +1 archive created + * SquareNumberLambda at /Users/YourUserName/SquareNumberLambda/.build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/SquareNumberLambda/SquareNumberLambda.zip + + +cp .build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/SquareNumberLambda/SquareNumberLambda.zip ~/Desktop diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-01-aws-cli.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-01-aws-cli.sh new file mode 100644 index 00000000..7a33b49d --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-01-aws-cli.sh @@ -0,0 +1 @@ +aws --version diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-02-lambda-invoke-hidden.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-02-lambda-invoke-hidden.sh new file mode 100644 index 00000000..9e66559e --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-02-lambda-invoke-hidden.sh @@ -0,0 +1,7 @@ +# +# --region the AWS Region to send the command +# --function-name the name of your function +# --cli-binary-format tells the cli to use raw data as input (default is base64) +# --payload the payload to pass to your function code +# result.json the name of the file to store the response from the function + diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-02-lambda-invoke.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-02-lambda-invoke.sh new file mode 100644 index 00000000..52c3c549 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-02-lambda-invoke.sh @@ -0,0 +1,14 @@ +# +# --region the AWS Region to send the command +# --function-name the name of your function +# --cli-binary-format tells the cli to use raw data as input (default is base64) +# --payload the payload to pass to your function code +# result.json the name of the file to store the response from the function + +aws lambda invoke \ + --region us-west-2 \ + --function-name SquaredNumberLambda \ + --cli-binary-format raw-in-base64-out \ + --payload '{"number":3}' \ + result.json + diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-03-lambda-invoke.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-03-lambda-invoke.sh new file mode 100644 index 00000000..569e75ea --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-03-lambda-invoke.sh @@ -0,0 +1,18 @@ +# +# --region the AWS Region to send the command +# --function-name the name of your function +# --cli-binary-format tells the cli to use raw data as input (default is base64) +# --payload the payload to pass to your function code +# result.json the name of the file to store the response from the function + +aws lambda invoke \ + --region us-west-2 \ + --function-name SquaredNumberLambda \ + --cli-binary-format raw-in-base64-out \ + --payload '{"number":3}' \ + result.json + +{ + "StatusCode": 200, + "ExecutedVersion": "$LATEST" +} diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-04-lambda-invoke.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-04-lambda-invoke.sh new file mode 100644 index 00000000..c31e7e4b --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-04-lambda-invoke.sh @@ -0,0 +1,20 @@ +# +# --region the AWS Region to send the command +# --function-name the name of your function +# --cli-binary-format tells the cli to use raw data as input (default is base64) +# --payload the payload to pass to your function code +# result.json the name of the file to store the response from the function + +aws lambda invoke \ + --region us-west-2 \ + --function-name SquaredNumberLambda \ + --cli-binary-format raw-in-base64-out \ + --payload '{"number":3}' \ + result.json + +{ + "StatusCode": 200, + "ExecutedVersion": "$LATEST" +} + +cat result.json diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-05-lambda-invoke.sh b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-05-lambda-invoke.sh new file mode 100644 index 00000000..54a198bd --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/code/04-03-05-lambda-invoke.sh @@ -0,0 +1,22 @@ +# +# --region the AWS Region to send the command +# --function-name the name of your function +# --cli-binary-format tells the cli to use raw data as input (default is base64) +# --payload the payload to pass to your function code +# result.json the name of the file to store the response from the function + +aws lambda invoke \ + --region us-west-2 \ + --function-name SquaredNumberLambda \ + --cli-binary-format raw-in-base64-out \ + --payload '{"number":3}' \ + result.json + +{ + "StatusCode": 200, + "ExecutedVersion": "$LATEST" +} + +cat result.json +{"result":9} + diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/00-swift_on_lambda.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/00-swift_on_lambda.png new file mode 100644 index 00000000..dcbeb6e0 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/00-swift_on_lambda.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/01-swift_on_lambda.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/01-swift_on_lambda.png new file mode 100644 index 00000000..90c5ba74 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/01-swift_on_lambda.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-01-terminal-package-init.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-01-terminal-package-init.png new file mode 100644 index 00000000..4e4a2f24 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-01-terminal-package-init.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-01-xcode@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-01-xcode@2x.png new file mode 100644 index 00000000..4aedcca1 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-01-xcode@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-01-xcode~dark@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-01-xcode~dark@2x.png new file mode 100644 index 00000000..d22af823 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-01-xcode~dark@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-02-swift-package-manager.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-02-swift-package-manager.png new file mode 100644 index 00000000..62f41427 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-02-swift-package-manager.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-03-01-rename-file@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-03-01-rename-file@2x.png new file mode 100644 index 00000000..53d681a9 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-03-01-rename-file@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-03-01-rename-file~dark@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-03-01-rename-file~dark@2x.png new file mode 100644 index 00000000..22e2814e Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-03-01-rename-file~dark@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-03-swift-code-xcode.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-03-swift-code-xcode.png new file mode 100644 index 00000000..90c5ba74 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-03-swift-code-xcode.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-01-edit-scheme@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-01-edit-scheme@2x.png new file mode 100644 index 00000000..7ad57885 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-01-edit-scheme@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-01-edit-scheme~dark@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-01-edit-scheme~dark@2x.png new file mode 100644 index 00000000..dc92b003 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-01-edit-scheme~dark@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-02-add-variable@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-02-add-variable@2x.png new file mode 100644 index 00000000..3393f211 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-02-add-variable@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-02-add-variable~dark@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-02-add-variable~dark@2x.png new file mode 100644 index 00000000..2b8e428d Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-02-add-variable~dark@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-test-locally.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-test-locally.png new file mode 100644 index 00000000..dba46581 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-04-test-locally.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-swift_on_lambda.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-swift_on_lambda.png new file mode 100644 index 00000000..ac9d2006 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/03-swift_on_lambda.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-01-01-docker-started@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-01-01-docker-started@2x.png new file mode 100644 index 00000000..e65aba1f Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-01-01-docker-started@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-01-compile-for-linux.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-01-compile-for-linux.png new file mode 100644 index 00000000..16ec0b5d Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-01-compile-for-linux.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-01-console-login@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-01-console-login@2x.png new file mode 100644 index 00000000..e51f6d81 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-01-console-login@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-02-console-login@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-02-console-login@2x.png new file mode 100644 index 00000000..e4cf04b5 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-02-console-login@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-03-select-region@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-03-select-region@2x.png new file mode 100644 index 00000000..05fb1343 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-03-select-region@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-04-select-lambda@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-04-select-lambda@2x.png new file mode 100644 index 00000000..f6f13344 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-04-select-lambda@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-05-create-function@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-05-create-function@2x.png new file mode 100644 index 00000000..d8c97d1e Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-05-create-function@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-05-create-function~dark@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-05-create-function~dark@2x.png new file mode 100644 index 00000000..0715079c Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-05-create-function~dark@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-06-create-function@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-06-create-function@2x.png new file mode 100644 index 00000000..e3877acb Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-06-create-function@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-06-create-function~dark@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-06-create-function~dark@2x.png new file mode 100644 index 00000000..76795ecd Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-06-create-function~dark@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-07-upload-zip@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-07-upload-zip@2x.png new file mode 100644 index 00000000..23fd565a Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-07-upload-zip@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-07-upload-zip~dark@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-07-upload-zip~dark@2x.png new file mode 100644 index 00000000..4503837b Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-07-upload-zip~dark@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-08-upload-zip@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-08-upload-zip@2x.png new file mode 100644 index 00000000..b47ecf34 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-08-upload-zip@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-08-upload-zip~dark@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-08-upload-zip~dark@2x.png new file mode 100644 index 00000000..cc630173 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-08-upload-zip~dark@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-09-test-lambda@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-09-test-lambda@2x.png new file mode 100644 index 00000000..865d23b3 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-09-test-lambda@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-09-test-lambda~dark@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-09-test-lambda~dark@2x.png new file mode 100644 index 00000000..b197f191 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-09-test-lambda~dark@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-10-test-lambda-result@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-10-test-lambda-result@2x.png new file mode 100644 index 00000000..174afb17 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-10-test-lambda-result@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-10-test-lambda-result~dark@2x.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-10-test-lambda-result~dark@2x.png new file mode 100644 index 00000000..61791e78 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-10-test-lambda-result~dark@2x.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-create-lambda.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-create-lambda.png new file mode 100644 index 00000000..70152ba5 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-02-create-lambda.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-03-invoke-lambda.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-03-invoke-lambda.png new file mode 100644 index 00000000..71167f24 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-03-invoke-lambda.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-swift_on_lambda.png b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-swift_on_lambda.png new file mode 100644 index 00000000..386bdef7 Binary files /dev/null and b/Sources/AWSLambdaRuntimeCore/Documentation.docc/Resources/tutorials/04-swift_on_lambda.png differ diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/quick-setup.md b/Sources/AWSLambdaRuntimeCore/Documentation.docc/quick-setup.md new file mode 100644 index 00000000..151fb8c3 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/quick-setup.md @@ -0,0 +1,147 @@ +# Getting Started Quickly + +Learn how to create your first project in 3 minutes. + +Follow these instructions to get a high-level overview of the steps to write, test, and deploy your first Lambda function written in Swift. + +For a detailed step-by-step instruction, follow the tutorial instead. + + + +For the impatient, keep reading. + +## High-level instructions + +Follow these 6 steps to write, test, and deploy a Lambda function in Swift. + +1. Create a Swift project for an executable target + +```sh +swift package init --type executable +``` + +2. Add dependencies on `AWSLambdaRuntime` library + +```swift +// swift-tools-version:5.8 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "YourProjetName", + platforms: [ + .macOS(.v12), + ], + products: [ + .executable(name: "YourFunctionName", targets: ["YourFunctionName"]), + ], + dependencies: [ + .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "1.0.0-alpha"), + ], + targets: [ + .executableTarget( + name: "YourFunctionName", + dependencies: [ + .product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"), + ], + path: "." + ), + ] +) +``` + +3. Write your function code. + +> Be sure to rename the `main.swift` file to something else. + +Extends the `SimpleLambdaHandler` protocol and implement `handle(_:context)`. + + +If your Lambda function is invoked by another AWS service, use the `AWSLambdaEvent` library at [https://github.com/swift-server/swift-aws-lambda-events](https://github.com/swift-server/swift-aws-lambda-events) + +```swift +import AWSLambdaRuntime + +struct Input: Codable { + let number: Double +} + +struct Number: Codable { + let result: Double +} + +@main +struct SquareNumberHandler: SimpleLambdaHandler { + typealias Event = Input + typealias Output = Number + + func handle(_ event: Input, context: LambdaContext) async throws -> Number { + Number(result: event.number * event.number) + } +} +``` + +4. Test your code locally + +```sh +export LOCAL_LAMBDA_SERVER_ENABLED=true + +swift run + +# Switch to another Terminal tab + +curl --header "Content-Type: application/json" \ + --request POST \ + --data '{"number": 3}' \ + http://localhost:7000/invoke + +{"result":9} +``` + +5. Build and package your code for AWS Lambda + +AWS Lambda runtime runs on Amazon Linux. You must compile your code for Amazon Linux. + +> Be sure to have [Docker](https://docs.docker.com/desktop/install/mac-install/) installed for this step. + +```sh +swift package --disable-sandbox plugin archive + +------------------------------------------------------------------------- +building "squarenumberlambda" in docker +------------------------------------------------------------------------- +updating "swift:amazonlinux2" docker image + amazonlinux2: Pulling from library/swift + Digest: sha256:5b0cbe56e35210fa90365ba3a4db9cd2b284a5b74d959fc1ee56a13e9c35b378 + Status: Image is up to date for swift:amazonlinux2 + docker.io/library/swift:amazonlinux2 +building "SquareNumberLambda" + Building for production... +... +------------------------------------------------------------------------- +archiving "SquareNumberLambda" +------------------------------------------------------------------------- +1 archive created + * SquareNumberLambda at /Users/YourUserName/SquareNumberLambda/.build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/SquareNumberLambda/SquareNumberLambda.zip + + +cp .build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/SquareNumberLambda/SquareNumberLambda.zip ~/Desktop +``` + +6. Deploy on AWS Lambda + +> Be sure [to have an AWS Account](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-creating.html) to follow these steps. + +- Connect to the [AWS Console](https://console.aws.amazon.com) +- Navigate to Lambda +- Create a function +- Select **Provide your own bootstrap on Amazon Linux 2** as **Runtime** +- Select an **Architecture** that matches the one of the machine where you build the code. Select **x86_64** when you build on Intel-based Macs or **arm64** for Apple Silicon-based Macs. +- Upload the ZIP create during step 5 +- Select the **Test** tab, enter a test event such as `{"number":3}` and select **Test** + +If the test succeeds, you will see the result: '{"result":9}' + + +Congratulations 🎉! You just wrote, test, build, and deployed a Lambda function written in Swift. diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/01-overview.tutorial b/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/01-overview.tutorial new file mode 100644 index 00000000..f4a922b1 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/01-overview.tutorial @@ -0,0 +1,18 @@ +@Article(time: 1) { + + @Intro(title: "Overview") + +This tutorial helps you to get started writing your first AWS Lambda function in Swift. You will use the `AWSLambdaRuntime` package to write code that can be deployed on AWS Lambda. + +You will learn three things: + +1. How to implement simple Lambda function and test it locally +2. How to build a Lambda function for deployment on AWS +3. How to deploy your Lambda function on AWS and invoke it + +It's a beginners' tutorial. The business logic of the function is very simple, it computes the square of a number passed as input parameter. This simplicity allows you to focus on the project setup and the deployment. You will deploy your code using the AWS Management Console. It is the easiest way to get started with AWS Lambda. + +If you have any questions or recommendations, please [leave your feedback on GitHub](https://github.com/swift-server/swift-aws-lambda-runtime/issues) so that you can get your question answered and this tutorial can be improved. + +*The following instructions were recorded on April 15, 2023 and the AWS Management Console may have changed since then. Feel free to raise an issue if you spot differences with our screenshots* +} \ No newline at end of file diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/02-what-is-lambda.tutorial b/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/02-what-is-lambda.tutorial new file mode 100644 index 00000000..da86703b --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/02-what-is-lambda.tutorial @@ -0,0 +1,28 @@ +@Article(time: 3) { + + @Intro(title: "What is AWS Lambda") + + + AWS Lambda is a compute service that lets you run code without provisioning or managing servers. Lambda runs your code on a high-availability compute infrastructure and performs all of the administration of the compute resources, including server and operating system maintenance, capacity provisioning and automatic scaling, and logging. With Lambda, you can run code for virtually any type of application or backend service. All you need to do is supply your code in [one of the languages that Lambda supports](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html), including Swift. + + You organize your code into [Lambda functions](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-concepts.html#gettingstarted-concepts-function). Lambda runs your function only when needed and scales automatically, from a few requests per day to thousands per second. You pay only for the compute time that you consume—there is no charge when your code is not running. For more information, see [AWS Lambda Pricing](http://aws.amazon.com/lambda/pricing/). + + Lambda is a highly available service. For more information, see the [AWS Lambda Service Level Agreement](https://aws.amazon.com/lambda/sla/). + + ### When to use AWS Lambda + + Lambda is an ideal compute service for many application scenarios, as long as you can run your application code using the Lambda [standard runtime environment](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtime-environment.html) and within the resources that Lambda provides. For example, you can use Lambda for: + + - Mobile backends: Build backends using Lambda and Amazon API Gateway to authenticate and process API requests. Use AWS Amplify to easily integrate your backend with your iOS, Android, Web, and React Native front ends. + + - Web applications: Combine Lambda with other AWS services to build powerful web applications that automatically scale up and down and run in a highly available configuration across multiple data centers. + + - File processing: Use Amazon Simple Storage Service (Amazon S3) to trigger Lambda data processing in real time after an upload. + + - Stream processing: Use Lambda and Amazon Kinesis to process real-time streaming data for application activity tracking, transaction order processing, click stream analysis, data cleansing, log filtering, indexing, social media analysis, Internet of Things (IoT) device data telemetry, and metering. + + - IoT backends: Build serverless backends using Lambda to handle web, mobile, IoT, and third-party API requests. + + When using Lambda, you are responsible only for your code. Lambda manages the compute fleet that offers a balance of memory, CPU, network, and other resources to run your code. Because Lambda manages these resources, you cannot log in to compute instances or customize the operating system on [provided runtimes](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html). Lambda performs operational and administrative activities on your behalf, including managing capacity, monitoring, and logging your Lambda functions. + +} diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/03-prerequisites.tutorial b/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/03-prerequisites.tutorial new file mode 100644 index 00000000..48b1b7c3 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/03-prerequisites.tutorial @@ -0,0 +1,18 @@ +@Article(time: 3) { + + @Intro(title: "Prerequisites") + + +This tutorial has been tested on macOS, since this is what most Swift developers work on. It should also work on Linux. + +To follow the instructions provided by this tutorial you'll need to meet a couple of prerequisites. + +- We expect you to have a basic understanding of the Swift programming language and be somewhat familiar with the terminal/console. You can follow this [guided tour to have an overview of Swift](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/guidedtour). [You can follow this short tutorial to learn about macOS commands and the Terminal](https://support.apple.com/guide/terminal/open-or-quit-terminal-apd5265185d-f365-44cb-8b09-71a064a42125/mac). + +- You'll need to have a text editor and the Swift toolchain installed. On macOS, you can use [Xcode](https://developer.apple.com/xcode/). On Linux, you must install [the Swift runtime and toolchain](https://www.swift.org/download/). On macOS and Linux, you may also use [VSCode](https://code.visualstudio.com/download) and the [Swift extension for VSCode](https://www.swift.org/blog/vscode-extension/). + +- To compile your Lambda function to run on AWS Lambda, you will need to install [Docker](https://docs.docker.com/desktop/install/mac-install/). This tutorial doesn't go into much detail what Docker is and what it does. Just remember that AWS Lambda functions run on Linux. Therefore, you have to compile your Swift Lambda function code for Linux. Docker allows you to start a Linux virtual machine where you will compile your Swift code before to deploy it on AWS Lambda. This tutorial contains all the commands you will have to type to interact with Docker. Follow [the instructions provided by Docker](https://docs.docker.com/desktop/install/mac-install/) to install Docker on your machine. + +- To deploy your Lambda function on AWS you need an [Amazon Web Service (AWS)](https://aws.amazon.com/what-is-aws/) account. [Follow these instructions to create an AWS account](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-creating.html). + +} diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/03-write-function.tutorial b/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/03-write-function.tutorial new file mode 100644 index 00000000..428e3c71 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/03-write-function.tutorial @@ -0,0 +1,223 @@ +@Tutorial(time: 15) { + @Intro(title: "Write your first Lambda function") { + Learn how to create your project, add dependencies, and create and test your first Lambda function in Swift. + } + + @Section(title: "Initialize a new project") { + @ContentAndMedia() { + Create a new swift project and open Xcode. + @Image(source: "03-01-terminal-package-init", alt: "A Terminal with package init command") + } + + @Steps { + + Start in your development folder. + + @Step { + Open a Terminal and create a directory for your Lambda function. + @Code(name: "Commands to type in the Terminal", file: 03-01-01-package-init.sh) + } + + @Step { + Initialize a new Swift package for an executable target. + @Code(name: "Commands to type in the Terminal", file: 03-01-02-package-init.sh) + } + + @Step { + Open Xcode in this newly created directory. + @Code(name: "Commands to type in the Terminal", file: 03-01-03-package-init.sh) + } + + @Step { + Alternatively, if you use VSCode, use the `code` command to open VSCode in your project repository. + @Code(name: "Commands to type in the Terminal", file: 03-01-04-package-init.sh) + } + + @Step { + In your development environment, expand the project if necessary and open the file `Package.swift`. + + If you are an iOS developer, you might wonder what is a `Package.swift`. In simple terms, your `Package.swift` defines the dependencies your code has and what products (libraries and/or executables) your code offers. + @Image(source: 03-01-xcode.png, alt: "project open in Xcode") + } + } + } + + @Section(title: "Add the project dependencies") { + @ContentAndMedia() { + Prepare `Package.swift` to define the project targets and dependencies. + @Image(source: "03-02-swift-package-manager.png", alt: "Swift Package Manager icon as a box") + } + @Steps { + @Step { + In the Xcode editor, replace the content of `Package.swift` with the file on the right side of the screen. + + It defines a package for a project named `SquareNumberLambda`. The package name only matters when you build a library that is used by other Swift packages. + + > Comments are important here, do not skip them. They define the minimum version of Swift to use. + @Code(name: "Package.swift", file: 03-02-01-package.swift) + } + @Step { + Add the `platform` section. + + It defines on which Apple platforms the code can be executed. Since Lambda functions are supposed to be run on Linux servers with Amazon Linux 2, it is reasonable to make them run only on macOS, for debugging for example. It does not make sense to run this code on iOS, iPadOS, tvOS, and watchOS. + @Code(name: "Package.swift", file: 03-02-02-package.swift) + } + @Step { + Add the `dependencies` section. + + It defines what external libraries your code depends on. To run code within AWS Lambda you'll need a runtime that handles the communication with the [Lambda Runtime Interface](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html). This is what the `AWSLambdaRuntime` is for. You import it by specifying its GitHub url: `https://github.com/swift-server/swift-aws-lambda-runtime.git`. + + @Code(name: "Package.swift", file: 03-02-03-package.swift) + } + @Step { + Add the `target` section. + + In the `targets` section you specify your own targets. They are pretty comparable to targets you specify within an Xcode project (that's probably why they share the name 😎). In our example we only want to create an executable that is called `SquareNumberLambda`. An executable must have an entrypoint. This can be either a `main.swift` or an object that is marked with `@main`. For Lambda we will use the `@main` approach. + + @Code(name: "Package.swift", file: 03-02-04-package.swift) + } + @Step { + Add the `product` section. + + To advertise our `executableTarget` as a product of our package, we add it to the `products` section. + @Code(name: "Package.swift", file: 03-02-05-package.swift) + } + + } + } + + @Section(title: "Write the function code") { + @ContentAndMedia() { + Now that our project structure is ready, let's write the code of your Lambda function. Perform the following steps in Xcode or another IDE of your choice. + + @Image(source: 03-03-swift-code-xcode, alt: "Swift code in Xcode") + } + + @Steps { + @Step { + Rename the file `main.swift` to something else. I typically use `Lambda.swift`. + + The `AWSLambdaRuntime` use the [`@main`](https://github.com/apple/swift-evolution/blob/main/proposals/0281-main-attribute.md) directive to designate the entry point in your code. + + >A `main.swift` file is always considered to be an entry point, even if it has no top-level code. Because of this, placing the @main-designated type in a `main.swift` file is an error. + + @Image(source: 03-03-01-rename-file, alt: "Rename the file in Xcode IDE") + } + + + @Step { + Remove the code generated and create a `@main struct` that implements the protocol `SimpleLambdaHandler` + + @Code(name: "Lambda.swift", file: 03-03-01-main.swift) + } + + @Step { + Add an import statement to import the `AWSLambdaRuntime` library. + @Code(name: "Lambda.swift", file: 03-03-02-main.swift) + } + + @Step { + Write the `handle(_:context:) async throws -> Output` function as defined in `SimpleLambdaHandler` protocol. + + The `handle(_:context:)` function is the entry point of the Lambda function. + @Code(name: "Lambda.swift", file: 03-03-03-main.swift) + } + + @Step { + Add the definition of the input and output parameters. + + Input and Output parameters must conform to the `Codable` protocol. This ensures that your Lambda function accepts a JSON input and creates a JSON output. + Your function can use any `Codable`. When your function is triggered by another AWS service, we modeled most of the input and output data format for you. You can add the dependency on https://github.com/swift-server/swift-aws-lambda-events and import `AWSLambdaEvents` in your code. + + @Code(name: "Lambda.swift", file: 03-03-04-main.swift) + } + + @Step { + Modify the `struct` and the `handle(_:context:)` function to use your input and output parameter types. + + @Code(name: "Lambda.swift", file: 03-03-05-main.swift) + } + + @Step { + Add your function-specific business logic. + + As mentioned earlier, this example is very simple, it just squares the number received as input. Your actual function can do whatever you want: call APIs, access a database, or any other task your business requires. + + @Code(name: "Lambda.swift", file: 03-03-06-main.swift) + } + + } + } + + @Section(title: "Test Your Code Locally") { + @ContentAndMedia() { + Before to deploy your Lambda to AWS, you want to ensure that it works on your local machine. + + The `AWSLambdaRuntime` embeds a simple web server you can start and use to send your requests to your Lambda function. + + @Image(source: 03-04-test-locally.png, alt: "Icons of succeeded and failed tests") + } + + @Steps { + + The embedded web server starts only when an environment variable is defined. You will edit the Run step of the target scheme to include the environment variable. This will allow you to run your code from Xcode. + + @Step { + Select `Edit Scheme` under `SquareNumberLambda` target. + + @Image(source: 03-04-01-edit-scheme.png, alt: "Menu entry to edit schemes") + } + + @Step { + Add the `LOCAL_LAMBDA_SERVER_ENABLED` environment variable, with a value of `true` under `Run` settings. + + @Image(source: 03-04-02-add-variable.png, alt: "Add environment variable under Run settings") + } + + @Step { + Compile and Run your project. You should see the following output in the console. + + @Code(name: "Console output", file: 03-04-03-console-output.sh) + } + + @Step { + Now that the local server started, open a Terminal and use `curl` or any other HTTP client to POST your input payload to `localhost:7000`. + + @Code(name: "curl command in a terminal", file: 03-04-04-curl.sh) + } + + @Step { + When you pass `{"number":3}`, you should receive the response `{"result":9}` + + > Do not forget to stop the running scheme when you're done. + @Code(name: "curl command in a terminal", file: 03-04-05-curl.sh) + } + + Alternatively, you can use the command line from the Terminal. + + @Step { + From a Terminal, set the `LOCAL_LAMBDA_SERVER_ENABLED` environment variable to `true` + @Code(name: "curl command in a terminal", file: 03-04-06-terminal.sh) + } + + @Step { + Use the command `swift run` to start the local embedded web server. + @Code(name: "curl command in a terminal", file: 03-04-07-terminal.sh) + } + + @Step { + You should see the following output in the console. + @Code(name: "curl command in a terminal", file: 03-04-08-terminal.sh) + } + + @Step { + Now that the local server started, open a second tab in the Terminal and use `curl` or any other HTTP client to POST your input payload to `localhost:7000`. + + > Do not forget to stop the local server with `CTRL-C` when you're done. + @Code(name: "curl command in a terminal", file: 03-04-04-curl.sh) + } + + } + } + +} diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/04-deploy-function.tutorial b/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/04-deploy-function.tutorial new file mode 100644 index 00000000..c2bc7552 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/04-deploy-function.tutorial @@ -0,0 +1,175 @@ +@Tutorial(time: 15) { + @Intro(title: "Deploy your function to AWS Lambda") { + Learn how to package your code for AWS Lambda and to deploy it using the AWS Management Console + } + + @Section(title: "Compile for Amazon Linux") { + @ContentAndMedia() { + Learn how to compile your code to run it on Amazon Linux. + + @Image(source: 04-01-compile-for-linux, alt: "Compile for Amazon Linux") + } + + @Steps { + + AWS Lambda runs on top of [Amazon Linux 2](https://aws.amazon.com/amazon-linux-2/). You must therefore compile your code for Linux. The AWS Lambda Runtime for Swift uses Docker to do so. Once the code is compiled, it must be assembled in a ZIP file before being deployed in the cloud. + The AWS Lambda Runtime for Swift provides a [Swift Package Manager plugin](https://github.com/apple/swift-package-manager/blob/main/Documentation/Plugins.md) to compile and zip your Lambda function in one simple step. + + @Step { + Be sure Docker is started on your machine. On macOS, you can check the Docker icon in the menu bar. + + @Image(source: 04-01-01-docker-started.png, alt: "Docker icon and menu on macOS") + } + + @Step { + In a terminal, invoke the `archive` command to build and zip your Lambda function. + + @Code(name: "Commands in a Terminal", file: 04-01-02-plugin-archive.sh) + } + + @Step { + The plugin starts a Docker container running Amazon Linux 2 and compile your Lambda function code. It then creates a zip file. When everything goes well, you should see an output similar to this one. + + @Code(name: "Commands in a Terminal", file: 04-01-03-plugin-archive.sh) + } + + @Step { + Copy the generated zip files to your Desktop or Download directory for easy access. I choose the Desktop. + + @Code(name: "Commands in a Terminal", file: 04-01-04-plugin-archive.sh) + } + } + } + + @Section(title: "Create an Lambda Function") { + @ContentAndMedia() { + Learn how to create a Lambda function using the AWS Management Console and to deploy your zip file + + @Image(source: 04-02-create-lambda.png, alt: "Create a Lambda function") + } + + @Steps { + + You will now deploy your code to AWS Lambda. To complete the remaining steps in this tutorial, you must have an AWS Account. You can [create an AWS Account by following these instructions](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-creating.html). + + @Step { + Open a web browser and navigate to [https://console.aws.amazon.com](https://console.aws.amazon.com). + + @Image(source: 04-02-01-console-login.png, alt: "AWS console login") + } + + @Step { + If you have an IAM user ID and password, select **IAM User**, otherwise proceed by entering your **Root user** email address and password. For this tutorial, I sign in using my IAM User ID. + + @Image(source: 04-02-02-console-login.png, alt: "AWS console login with IAM user") + } + + @Step { + On the top right side of the console, select the AWS Region where you want to deploy your Lambda function. You typically choose a Region close to your customers to minimize the network latency. For this demo, I selected **Oregon (us-west-2)** + + > AWS has multiple Regions across all continents. You can learn more about [AWS Global Infrastructure](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/) here. + + @Image(source: 04-02-03-select-region.png, alt: "AWS console - Select Region") + } + + @Step { + On the top left side of the console, select the Lambda service to navigate to the Lambda section of the console. + + @Image(source: 04-02-04-select-lambda.png, alt: "AWS console - Select Lambda") + } + + @Step { + On the top right side of the console, select **Create function**. + + @Image(source: 04-02-05-create-function.png, alt: "Create function") + } + + @Step { + Enter a **Function name**. I choose `SquaredNumberLambda`. Select `Provide your own bootstrap on Amazon Linux 2` as **Runtime**. And select `arm64` as **Architecture** when you build on a Mac with Apple Silicon. Leave all other parameter as default, and select **Create function** on the bottom right part. + + > The runtime architecture for Lambda (`arm64` or `x86_64`) must match the one of the machine where you compiled the code. When you compiled on an Intel-based Mac, use `x86_64`. When compiling on an Apple Silicon-based Mac select `arm64`. + + + @Image(source: 04-02-06-create-function.png, alt: "Create function details") + } + + @Step { + On the next screen, select **.zip file** from the **Upload from** selection box on the middle right part of the screen. + + @Image(source: 04-02-07-upload-zip.png, alt: "Upload ") + } + + @Step { + Select the zip file that was generated earlier and select **Save**. + + @Image(source: 04-02-08-upload-zip.png, alt: "Create function") + } + + @Step { + To verify everything works well, create a test event and invoke the function from the **Test** tab in the console. Enter `MyTestEvent` as **Event name**. Enter `{"number":3}` as **Event JSON**. Then, select **Test**. + + @Image(source: 04-02-09-test-lambda.png, alt: "Create function") + } + + @Step { + When the invocation succeeds, you can see the execution details and the result: `{ "result" : 9 }`. + + > The execution result also shares the execution duration, the actual memory consumed and the logs generated by the function. These are important data to help you to fine-tune your function. Providing the function with more memory will also give it more compute power, resulting in lower execution time. + + @Image(source: 04-02-10-test-lambda-result.png, alt: "Create function") + } + + } + } + + @Section(title: "Invoke your Lambda function") { + @ContentAndMedia() { + Learn how to invoke the Lambda function using the AWS Lambda API and the AWS command line. + + @Image(source: 04-03-invoke-lambda.png, alt: "Invoke a Lambda function") + } + + @Steps { + + Typically you will [associate an URL to your Lambda function](https://docs.aws.amazon.com/lambda/latest/dg/lambda-urls.html), or [you will expose the Lambda function through a REST API](https://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started-with-lambda-integration.html). You might use the [Serverless Application Model (SAM)](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) to do so. We'll leave tasks for another tutorial. + + In the remaining section of this tutorial, you will learn how to invoke your Lambda function from the AWS command-line tool. + + @Step { + First, check that you have the `aws` command line tool installed and configured. + + > You can install the `aws` CLI with the command `brew awscli`. You need to configure the `aws` CLI with your AWS credentials. You may use the command `aws configure` to configure the CLI. [The AWS CLI documentation has more details](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-quickstart.html). + + @Code(name: "Command to type in the Terminal", file: 04-03-01-aws-cli.sh) + } + + @Step { + Enter the following command to invoke your Lambda function. + + @Code(name: "Command to type in the Terminal", file: 04-03-02-lambda-invoke.sh, previousFile: 04-03-02-lambda-invoke-hidden.sh) + + } + + @Step { + The command returns with the invocation status. + + @Code(name: "Command to type in the Terminal", file: 04-03-03-lambda-invoke.sh) + + } + + @Step { + Type `cat result.json` to see the value returned by your function. + + @Code(name: "Command to type in the Terminal", file: 04-03-04-lambda-invoke.sh) + + } + @Step { + When everything goes well, you will see `{ "result" : 9}`. Congratulation 🎉 ! + + @Code(name: "Command to type in the Terminal", file: 04-03-05-lambda-invoke.sh) + + } + } + } + +} diff --git a/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/table-of-content.tutorial b/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/table-of-content.tutorial new file mode 100644 index 00000000..aa1e26b3 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/Documentation.docc/tutorials/table-of-content.tutorial @@ -0,0 +1,28 @@ +@Tutorials(name: "AWS Lambda functions in Swift") { + @Intro(title: "Your First Lambda Function Written in Swift") { + A step-by-step tutorial to learn how to implement, build, test, and deploy your first Lambda function written in Swift. + @Image(source: "00-swift_on_lambda.png", alt: "Swift on AWS Lambda icons") + } + + @Chapter(name: "Before getting started") { + + @Image(source: "01-swift_on_lambda.png", alt: "A Swift project open in Xcode") + An overview of what to expect and what you need before getting started. + @TutorialReference(tutorial: "doc:01-overview") + @TutorialReference(tutorial: "doc:02-what-is-lambda") + @TutorialReference(tutorial: "doc:03-prerequisites") + } + @Chapter(name: "Your first Lambda function in Swift") { + + @Image(source: "03-swift_on_lambda.png", alt: "Swift Icon") + Create your first function and test it locally + @TutorialReference(tutorial: "doc:03-write-function") + } + @Chapter(name: "Deploy your code to the cloud") { + + @Image(source: "04-swift_on_lambda.png", alt: "Deploying Swift into AWS Lambda") + Build, package, upload, and invoke your code on AWS Lambda. + @TutorialReference(tutorial: "doc:04-deploy-function") + } + +}