Skip to content

Commit 481037b

Browse files
committed
add hummingbirdLambda example
1 parent 0a6af5b commit 481037b

File tree

5 files changed

+192
-0
lines changed

5 files changed

+192
-0
lines changed

Examples/Humingbird/.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
xcuserdata/
5+
DerivedData/
6+
.swiftpm/configuration/registries.json
7+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8+
.netrc
9+
samconfig.toml

Examples/Humingbird/Package.swift

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// swift-tools-version: 6.1
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
// needed for CI to test the local version of the library
7+
import struct Foundation.URL
8+
9+
let package = Package(
10+
name: "HBLambda",
11+
platforms: [.macOS(.v15)],
12+
dependencies: [
13+
.package(
14+
url: "https://github.com/swift-server/swift-aws-lambda-runtime.git",
15+
from: "2.0.0-beta.1"
16+
),
17+
.package(
18+
url: "https://github.com/hummingbird-project/hummingbird-lambda.git",
19+
branch: "main"
20+
),
21+
.package(url: "https://github.com/swift-server/swift-aws-lambda-events.git", from: "1.1.0"),
22+
],
23+
targets: [
24+
.executableTarget(
25+
name: "HBLambda",
26+
dependencies: [
27+
.product(name: "HummingbirdLambda", package: "hummingbird-lambda"),
28+
.product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"),
29+
]
30+
)
31+
]
32+
)
33+
34+
if let localDepsPath = Context.environment["LAMBDA_USE_LOCAL_DEPS"],
35+
localDepsPath != "",
36+
let v = try? URL(fileURLWithPath: localDepsPath).resourceValues(forKeys: [.isDirectoryKey]),
37+
v.isDirectory == true
38+
{
39+
// when we use the local runtime as deps, let's remove the dependency added above
40+
let indexToRemove = package.dependencies.firstIndex { dependency in
41+
if case .sourceControl(
42+
name: _,
43+
location: "https://github.com/swift-server/swift-aws-lambda-runtime.git",
44+
requirement: _
45+
) = dependency.kind {
46+
return true
47+
}
48+
return false
49+
}
50+
if let indexToRemove {
51+
package.dependencies.remove(at: indexToRemove)
52+
}
53+
54+
// then we add the dependency on LAMBDA_USE_LOCAL_DEPS' path (typically ../..)
55+
print("[INFO] Compiling against swift-aws-lambda-runtime located at \(localDepsPath)")
56+
package.dependencies += [
57+
.package(name: "swift-aws-lambda-runtime", path: localDepsPath)
58+
]
59+
}

Examples/Humingbird/README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Hummingbird Lambda
2+
3+
This is a simple example of an AWS Lambda function using the [Hummingbird](https://github.com/hummingbird-project/hummingbird) web framework, invoked through an Amazon API Gateway.
4+
5+
## Code
6+
7+
The Lambda function uses Hummingbird's router to handle HTTP requests. It defines a simple GET endpoint at `/hello` that returns "Hello".
8+
9+
The code creates a `Router` with `AppRequestContext` (which is a type alias for `BasicLambdaRequestContext<APIGatewayV2Request>`). The router defines HTTP routes using Hummingbird's familiar syntax.
10+
11+
The `APIGatewayV2LambdaFunction` wraps the Hummingbird router to make it compatible with AWS Lambda and API Gateway V2 events.
12+
13+
`APIGatewayV2Request` is defined in the [Swift AWS Lambda Events](https://github.com/swift-server/swift-aws-lambda-events) library, and the Hummingbird Lambda integration is provided by the [Hummingbird Lambda](https://github.com/hummingbird-project/hummingbird-lambda) package.
14+
15+
## Build & Package
16+
17+
To build the package, type the following commands.
18+
19+
```bash
20+
swift build
21+
swift package archive --allow-network-connections docker
22+
```
23+
24+
If there is no error, there is a ZIP file ready to deploy.
25+
The ZIP file is located at `.build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/HBLambda/HBLambda.zip`
26+
27+
## Deploy
28+
29+
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.
30+
31+
**Prerequisites** : Install the [SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html)
32+
33+
The example directory contains a file named `template.yaml` that describes the deployment.
34+
35+
To actually deploy your Lambda function and create the infrastructure, type the following `sam` command.
36+
37+
```bash
38+
sam deploy \
39+
--resolve-s3 \
40+
--template-file template.yaml \
41+
--stack-name HummingbirdLambda \
42+
--capabilities CAPABILITY_IAM
43+
```
44+
45+
At the end of the deployment, the script lists the API Gateway endpoint.
46+
The output is similar to this one.
47+
48+
```
49+
-----------------------------------------------------------------------------------------------------------------------------
50+
Outputs
51+
-----------------------------------------------------------------------------------------------------------------------------
52+
Key APIGatewayEndpoint
53+
Description API Gateway endpoint URL"
54+
Value https://a5q74es3k2.execute-api.us-east-1.amazonaws.com
55+
-----------------------------------------------------------------------------------------------------------------------------
56+
```
57+
58+
## Invoke your Lambda function
59+
60+
To invoke the Lambda function, use this `curl` command line to call the `/hello` endpoint.
61+
62+
```bash
63+
curl https://a5q74es3k2.execute-api.us-east-1.amazonaws.com/hello
64+
```
65+
66+
Be sure to replace the URL with the API Gateway endpoint returned in the previous step.
67+
68+
This should print:
69+
70+
```bash
71+
Hello
72+
```
73+
74+
## Undeploy
75+
76+
When done testing, you can delete the infrastructure with this command.
77+
78+
```bash
79+
sam delete
80+
```
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import AWSLambdaEvents
2+
import HummingbirdLambda
3+
import Logging
4+
5+
typealias AppRequestContext = BasicLambdaRequestContext<APIGatewayV2Request>
6+
let router = Router(context: AppRequestContext.self)
7+
8+
router.get("hello") { _, _ in
9+
"Hello"
10+
}
11+
12+
let lambda = APIGatewayV2LambdaFunction(router: router)
13+
try await lambda.runService()

Examples/Humingbird/template.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
AWSTemplateFormatVersion: '2010-09-09'
2+
Transform: AWS::Serverless-2016-10-31
3+
Description: SAM Template for Hummingbird Lambda Example
4+
5+
Resources:
6+
# Lambda function
7+
HBLambda:
8+
Type: AWS::Serverless::Function
9+
Properties:
10+
CodeUri: .build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/HBLambda/HBLambda.zip
11+
Timeout: 60
12+
Handler: swift.bootstrap # ignored by the Swift runtime
13+
Runtime: provided.al2
14+
MemorySize: 512
15+
Architectures:
16+
- arm64
17+
Environment:
18+
Variables:
19+
# by default, AWS Lambda runtime produces no log
20+
# use `LOG_LEVEL: debug` for for lifecycle and event handling information
21+
# use `LOG_LEVEL: trace` for detailed input event information
22+
LOG_LEVEL: debug
23+
Events:
24+
HttpApiEvent:
25+
Type: HttpApi
26+
27+
Outputs:
28+
# print API Gateway endpoint
29+
APIGatewayEndpoint:
30+
Description: API Gateway endpoint URI"
31+
Value: !Sub "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com"

0 commit comments

Comments
 (0)