Skip to content

Restructure Examples folder #387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ xcuserdata
Package.resolved
.serverless
.vscode
Makefile
2 changes: 2 additions & 0 deletions Examples/APIGateway/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
samconfig.toml
Makefile
55 changes: 55 additions & 0 deletions Examples/APIGateway/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// swift-tools-version:6.0

import PackageDescription

// needed for CI to test the local version of the library
import class Foundation.ProcessInfo
import struct Foundation.URL

#if os(macOS)
let platforms: [PackageDescription.SupportedPlatform]? = [.macOS(.v15)]
#else
let platforms: [PackageDescription.SupportedPlatform]? = nil
#endif

let package = Package(
name: "swift-aws-lambda-runtime-example",
platforms: platforms,
products: [
.executable(name: "APIGAtewayLambda", targets: ["APIGAtewayLambda"])
],
dependencies: [
// dependency on swift-aws-lambda-runtime is added dynamically below
// .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", branch: "main")

.package(url: "https://github.com/swift-server/swift-aws-lambda-events.git", branch: "main")
],
targets: [
.executableTarget(
name: "APIGAtewayLambda",
dependencies: [
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
.product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"),
],
path: "."
)
]
)

if let localDepsPath = ProcessInfo.processInfo.environment["LAMBDA_USE_LOCAL_DEPS"],
localDepsPath != "",
let v = try? URL(fileURLWithPath: localDepsPath).resourceValues(forKeys: [.isDirectoryKey]),
let _ = v.isDirectory
{
print("[INFO] Compiling against swift-aws-lambda-runtime located at \(localDepsPath)")
package.dependencies += [
.package(name: "swift-aws-lambda-runtime", path: localDepsPath)
]

} else {
print("[INFO] LAMBDA_USE_LOCAL_DEPS is not pointing to your local swift-aws-lambda-runtime code")
print("[INFO] This project will compile against the main branch of the Lambda Runtime on GitHub")
package.dependencies += [
.package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", branch: "main")
]
}
124 changes: 124 additions & 0 deletions Examples/APIGateway/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# API Gateway

This is a simple example of an AWS Lambda function invoked through an Amazon API Gateway.

## Code

The Lambda function takes all HTTP headers it receives as input and returns them as output.

The code creates a `LambdaRuntime` struct. In it's simplest form, the initializer takes a function as argument. The function is the handler that will be invoked when the API Gateway receives an HTTP request.

The handler is `(event: APIGatewayV2Request, context: LambdaContext) -> APIGatewayV2Response`. The function takes two arguments:
- the event argument is a `APIGatewayV2Request`. It is the parameter passed by the API Gateway. It contains all data passed in the HTTP request and some meta data.
- the context argument is a `Lambda Context`. It is a description of the runtime context.

The function must return a `APIGatewayV2Response`.

`APIGatewayV2Request` and `APIGatewayV2Response` are defined in the [Swift AWS Lambda Events](https://github.com/swift-server/swift-aws-lambda-events) library.

## Build & Package

To build the package, type the following commands.

```bash
swift build
swift package archive --disable-sandbox
```

If there is no error, there is a ZIP file ready to deploy.
The ZIP file is located at `.build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/MyLambda/MyLambda.zip`

## Deploy

The deployment must include the Lambda function and the API Gateway. We use the [Serverless Application Model (SAM)](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) to deploy the infrastructure.

**Prerequisites** : Install the [SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html)

The example directory contains a file named `template.yaml` that describes the deployment.

To actually deploy your Lambda function and create the infrastructure, type the following `sam` command.

```bash
sam deploy \
----resolve-s3 \
--template-file template.yaml \
--stack-name MyLambda \
--capabilities CAPABILITY_IAM
```

At the end of the deployment, the script lists the API Gateway endpoint.
The output is similar to this one.

```
-----------------------------------------------------------------------------------------------------------------------------
Outputs
-----------------------------------------------------------------------------------------------------------------------------
Key APIGAtewayEndpoint
Description API Gateway endpoint UR"
Value https://a5q74es3k2.execute-api.us-east-1.amazonaws.com
-----------------------------------------------------------------------------------------------------------------------------
```

## Invoke your Lambda function

To invoke the Lambda function, use this `curl` command line.

```bash
curl https://a5q74es3k2.execute-api.us-east-1.amazonaws.com
```

Be sure to replace the URL with the API Gateway endpoint returned in the previous step.

This should print a JSON similar to

```bash
{"version":"2.0","rawPath":"\/","isBase64Encoded":false,"rawQueryString":"","headers":{"user-agent":"curl\/8.7.1","accept":"*\/*","host":"a5q74es3k2.execute-api.us-east-1.amazonaws.com","content-length":"0","x-amzn-trace-id":"Root=1-66fb0388-691f744d4bd3c99c7436a78d","x-forwarded-port":"443","x-forwarded-for":"81.0.0.43","x-forwarded-proto":"https"},"requestContext":{"requestId":"e719cgNpoAMEcwA=","http":{"sourceIp":"81.0.0.43","path":"\/","protocol":"HTTP\/1.1","userAgent":"curl\/8.7.1","method":"GET"},"stage":"$default","apiId":"a5q74es3k2","time":"30\/Sep\/2024:20:01:12 +0000","timeEpoch":1727726472922,"domainPrefix":"a5q74es3k2","domainName":"a5q74es3k2.execute-api.us-east-1.amazonaws.com","accountId":"012345678901"}
```

If you have `jq` installed, you can use it to pretty print the output.

```bash
curl -s https://a5q74es3k2.execute-api.us-east-1.amazonaws.com | jq
{
"version": "2.0",
"rawPath": "/",
"requestContext": {
"domainPrefix": "a5q74es3k2",
"stage": "$default",
"timeEpoch": 1727726558220,
"http": {
"protocol": "HTTP/1.1",
"method": "GET",
"userAgent": "curl/8.7.1",
"path": "/",
"sourceIp": "81.0.0.43"
},
"apiId": "a5q74es3k2",
"accountId": "012345678901",
"requestId": "e72KxgsRoAMEMSA=",
"domainName": "a5q74es3k2.execute-api.us-east-1.amazonaws.com",
"time": "30/Sep/2024:20:02:38 +0000"
},
"rawQueryString": "",
"routeKey": "$default",
"headers": {
"x-forwarded-for": "81.0.0.43",
"user-agent": "curl/8.7.1",
"host": "a5q74es3k2.execute-api.us-east-1.amazonaws.com",
"accept": "*/*",
"x-amzn-trace-id": "Root=1-66fb03de-07533930192eaf5f540db0cb",
"content-length": "0",
"x-forwarded-proto": "https",
"x-forwarded-port": "443"
},
"isBase64Encoded": false
}
```

## Undeploy

When done testing, you can delete the infrastructure with this command.

```bash
sam delete
```
40 changes: 40 additions & 0 deletions Examples/APIGateway/Sources/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2024 Apple Inc. and the SwiftAWSLambdaRuntime project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import AWSLambdaEvents
import AWSLambdaRuntime

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif

let encoder = JSONEncoder()
let runtime = LambdaRuntime {
(event: APIGatewayV2Request, context: LambdaContext) -> APIGatewayV2Response in

var header = HTTPHeaders()
context.logger.debug("HTTP API Message received")

header["content-type"] = "application/json"

// echo the request in the response
let data = try encoder.encode(event)
let response = String(decoding: data, as: Unicode.UTF8.self)

return APIGatewayV2Response(statusCode: .ok, headers: header, body: response)
}

try await runtime.run()
31 changes: 31 additions & 0 deletions Examples/APIGateway/template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: SAM Template for QuoteService

Resources:
# Lambda function
APIGAtewayLambda:
Type: AWS::Serverless::Function
Properties:
CodeUri: .build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/APIGAtewayLambda/APIGAtewayLambda.zip
Timeout: 60
Handler: swift.bootstrap
Runtime: provided.al2
MemorySize: 512
Architectures:
- arm64
Environment:
Variables:
# by default, AWS Lambda runtime produces no log
# use `LOG_LEVEL: debug` for for lifecycle and event handling information
# use `LOG_LEVEL: trace` for detailed input event information
LOG_LEVEL: trace
Events:
HttpApiEvent:
Type: HttpApi

Outputs:
# print API Gateway endpoint
APIGAtewayEndpoint:
Description: API Gateway endpoint UR"
Value: !Sub "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com"
32 changes: 0 additions & 32 deletions Examples/Benchmark/BenchmarkHandler.swift

This file was deleted.

34 changes: 0 additions & 34 deletions Examples/Benchmark/Package.swift

This file was deleted.

1 change: 0 additions & 1 deletion Examples/Deployment/.dockerignore

This file was deleted.

3 changes: 0 additions & 3 deletions Examples/Deployment/Dockerfile

This file was deleted.

43 changes: 0 additions & 43 deletions Examples/Deployment/Package.swift

This file was deleted.

Loading
Loading