Skip to content

Commit e93b1c0

Browse files
committed
Update library to support Swift Lambda runtime v2
1 parent 4cb7c71 commit e93b1c0

29 files changed

+553
-737
lines changed

.gitignore

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
.DS_Store
2-
/.aws-sam/
3-
/.build
4-
/.swiftpm
2+
.aws-sam/
3+
.build
4+
.index-build
5+
.swiftpm
56
samconfig.toml
67
Package.resolved
78
/*.xcodeproj
@@ -10,4 +11,3 @@ DerivedData/
1011
.swiftpm/config/registries.json
1112
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
1213
*key
13-

.swift-format

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
"UseLetInEveryBoundCaseVariable" : false,
5353
"UseShorthandTypeNames" : true,
5454
"UseSingleLinePropertyGetter" : false,
55-
"UseSynthesizedInitializer" : true,
55+
"UseSynthesizedInitializer" : false,
5656
"UseWhereClausesInForLoops" : false
5757
},
5858
"spacesAroundRangeFormationOperators" : false,

Examples/quoteapi/.gitignore

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
/.aws-sam
2-
/.build
3-
/.swiftpm
4-
/.vscode
1+
.aws-sam
2+
.build
3+
.index-build
4+
.swiftpm
5+
.vscode
56
Package.resolved
67
samconfig.toml
78
*.d

Examples/quoteapi/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# image used to compile your Swift code
2-
FROM public.ecr.aws/docker/library/swift:5.9.1-amazonlinux2
2+
FROM public.ecr.aws/docker/library/swift:6.1-amazonlinux2
33
RUN yum -y install git jq tar zip openssl-devel

Examples/quoteapi/Makefile

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
### Add functions here and link them to builder-bot format MUST BE "build-FunctionResourceName in template.yaml"
22

33
build-QuoteService: builder-bot
4+
build-LambdaAuthorizer: builder-bot
45

56
# Helper commands
67
build:
@@ -10,16 +11,20 @@ deploy:
1011
sam deploy
1112

1213
logs:
13-
sam logs --stack-name QuoteService --name QuoteService
14+
sam logs --stack-name QuoteService
1415

1516
tail:
16-
sam logs --stack-name QuoteService --name QuoteService --tail
17+
sam logs --stack-name QuoteService --tail
1718

1819
local:
19-
LOCAL_LAMBDA_SERVER_ENABLED=true swift run QuoteService
20+
swift run QuoteService
21+
22+
local-invoke:
23+
curl -v -H 'Authorization: Bearer 123' -X POST --data @events/GetQuote.json http://127.0.0.1:7000/invoke
2024

2125
invoke:
22-
curl -v -H 'Authorization: 123' https://k3lbszo7x6.execute-api.us-east-1.amazonaws.com/stocks/AAPL
26+
## curl -v -H 'Authorization: Bearer 123' https://<REPLACE_WITH_YOUR_API_URI>/stocks/AAPL
27+
curl -v -H 'Authorization: Bearer 123' https://lq2rria2n6.execute-api.us-east-1.amazonaws.com/stocks/AAPL
2328

2429
###################### No Change required below this line ##########################
2530

@@ -30,17 +35,15 @@ builder-bot:
3035
$(eval $@ARTIFACTS_DIR = $(PWD)/.aws-sam/build/$($@PRODUCT))
3136

3237
## Building from swift-openapi-lambda in a local directory (not from Github)
33-
## 1. git clone https://github.com/swift-server/swift-openapi-lambda ..
34-
## 2. Change `Package.swift` dependency to ../swift-openapi-lambda
35-
36-
## 3. add /.. to BUILD_SRC
37-
## $(eval $@BUILD_SRC = $(PWD)/..)
38-
$(eval $@BUILD_SRC = $(PWD))
38+
## 2. Change `Package.swift` dependency to path: "../.."
3939

40-
## 4. add `cd quoteapi &&` to the docker BUILD_CMD
41-
## $(eval $@BUILD_CMD = "ls && cd quoteapi && swift build --static-swift-stdlib --product $($@PRODUCT) -c release --build-path /build-target")
40+
## 3. add /../.. to BUILD_SRC
41+
$(eval $@BUILD_SRC = $(PWD)/../..)
42+
## $(eval $@BUILD_SRC = $(PWD))
4243

43-
$(eval $@BUILD_CMD = "swift build --static-swift-stdlib --product $($@PRODUCT) -c release --build-path /build-target")
44+
## 4. add `cd Examples/quoteapi &&` to the docker BUILD_CMD
45+
$(eval $@BUILD_CMD = "ls && cd Examples/quoteapi && swift build --static-swift-stdlib --product $($@PRODUCT) -c release --build-path /build-target")
46+
## $(eval $@BUILD_CMD = "swift build --static-swift-stdlib --product $($@PRODUCT) -c release --build-path /build-target")
4447

4548
# build docker image to compile Swift for Linux
4649
docker build -f Dockerfile . -t swift-builder

Examples/quoteapi/Package.swift

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
1-
// swift-tools-version: 5.9
1+
// swift-tools-version: 6.0
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
55

66
let package = Package(
77
name: "QuoteService",
88
platforms: [
9-
.macOS(.v13), .iOS(.v15), .tvOS(.v15), .watchOS(.v6),
9+
.macOS(.v15)
1010
],
1111
products: [
1212
.executable(name: "QuoteService", targets: ["QuoteService"])
1313
],
1414
dependencies: [
1515
.package(url: "https://github.com/apple/swift-openapi-generator.git", from: "1.4.0"),
16-
.package(url: "https://github.com/apple/swift-openapi-runtime.git", from: "1.5.0"),
17-
.package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "1.0.0-alpha.3"),
18-
.package(url: "https://github.com/swift-server/swift-aws-lambda-events.git", from: "0.4.0"),
19-
.package(url: "https://github.com/swift-server/swift-openapi-lambda.git", from: "0.2.0"),
20-
// .package(name: "swift-openapi-lambda", path: "../swift-openapi-lambda")
16+
.package(url: "https://github.com/apple/swift-openapi-runtime.git", from: "1.8.2"),
17+
.package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "2.0.0-beta.3"),
18+
.package(url: "https://github.com/swift-server/swift-aws-lambda-events.git", from: "1.2.0"),
19+
// .package(url: "https://github.com/swift-server/swift-openapi-lambda.git", from: "0.3.0"),
20+
.package(name: "swift-openapi-lambda", path: "../.."),
21+
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.8.0")
2122
],
2223
targets: [
2324
.executableTarget(
@@ -27,8 +28,9 @@ let package = Package(
2728
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
2829
.product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"),
2930
.product(name: "OpenAPILambda", package: "swift-openapi-lambda"),
31+
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle")
3032
],
31-
path: "Sources",
33+
path: "Sources/QuoteAPI",
3234
resources: [
3335
.copy("openapi.yaml"),
3436
.copy("openapi-generator-config.yaml"),
@@ -39,6 +41,14 @@ let package = Package(
3941
package: "swift-openapi-generator"
4042
)
4143
]
42-
)
44+
),
45+
.executableTarget(
46+
name: "LambdaAuthorizer",
47+
dependencies: [
48+
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
49+
.product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"),
50+
],
51+
path: "Sources/LambdaAuthorizer"
52+
),
4353
]
4454
)

Examples/quoteapi/README.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ The **sam build** command uses Docker to compile your Swift Lambda function and
2020
sam build
2121
```
2222

23+
On macOS, you might need to run this command if `sam` doesn't see `docker`:
24+
```bash
25+
export DOCKER_HOST=unix://$HOME/.docker/run/docker.sock
26+
```
27+
2328
## Deploy the application
2429

2530
The **sam deploy** command creates the Lambda function and API Gateway in your AWS account.
@@ -28,13 +33,7 @@ The **sam deploy** command creates the Lambda function and API Gateway in your A
2833
sam deploy --guided
2934
```
3035

31-
Accept the default response to every prompt, except the following warning:
32-
33-
```bash
34-
QuoteService may not have authorization defined, Is this okay? [y/N]: y
35-
```
36-
37-
The project creates a publicly accessible API endpoint. This is a warning to inform you the API does not have authorization. If you are interested in adding authorization to the API, please refer to the [SAM Documentation](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-httpapi.html).
36+
The project creates an API endpoint protected by a bearer token authorization. Use token value '123' while testing. Youc an change the token validation logic in the `LambdaAuthorizer` function. To learn more about Lambda authorizer function, refer to [the API Gateway documentation](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html).
3837

3938
## Use the API
4039

@@ -54,7 +53,7 @@ Use cURL or a tool such as [Postman](https://www.postman.com/) to interact with
5453
**Invoke the API Endpoint**
5554

5655
```bash
57-
curl https://[your-api-endpoint]/stocks/AMZN
56+
curl -H 'Authorization: Bearer 123' https://[your-api-endpoint]/stocks/AMZN
5857
```
5958

6059
## Test the API Locally
@@ -70,6 +69,11 @@ When a Lambda function is invoked, API Gateway sends an event to the function wi
7069
sam local invoke QuoteService --event events/GetQuote.json
7170
```
7271

72+
On macOS, you might need to run this command if `sam` doesn't see `docker`:
73+
```bash
74+
export DOCKER_HOST=unix://$HOME/.docker/run/docker.sock
75+
```
76+
7377
## Cleanup
7478

7579
When finished with your application, use SAM to delete it from your AWS account. Answer **Yes (y)** to all prompts. This will delete all of the application resources created in your AWS account.
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift OpenAPI Lambda open source project
4+
//
5+
// Copyright (c) 2023 Amazon.com, Inc. or its affiliates
6+
// and the Swift OpenAPI Lambda project authors
7+
// Licensed under Apache License v2.0
8+
//
9+
// See LICENSE.txt for license information
10+
// See CONTRIBUTORS.txt for the list of Swift OpenAPI Lambda project authors
11+
//
12+
// SPDX-License-Identifier: Apache-2.0
13+
//
14+
//===----------------------------------------------------------------------===//
15+
16+
//===----------------------------------------------------------------------===//
17+
//
18+
// This source file is part of the SwiftAWSLambdaRuntime open source project
19+
//
20+
// Copyright (c) 2024 Apple Inc. and the SwiftAWSLambdaRuntime project authors
21+
// Licensed under Apache License v2.0
22+
//
23+
// See LICENSE.txt for license information
24+
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
25+
//
26+
// SPDX-License-Identifier: Apache-2.0
27+
//
28+
//===----------------------------------------------------------------------===//
29+
30+
import AWSLambdaEvents
31+
import AWSLambdaRuntime
32+
33+
//
34+
// This is an example of a policy authorizer that always authorizes the request.
35+
// The policy authorizer returns an IAM policy document that defines what the Lambda function caller can do and optional context key-value pairs
36+
//
37+
// This code is shown for the example only and is not used in this demo.
38+
// This code doesn't perform any type of token validation. It should be used as a reference only.
39+
// let policyAuthorizerHandler:
40+
// (APIGatewayLambdaAuthorizerRequest, LambdaContext) async throws -> APIGatewayLambdaAuthorizerPolicyResponse = {
41+
// (request: APIGatewayLambdaAuthorizerRequest, context: LambdaContext) in
42+
43+
// context.logger.debug("+++ Policy Authorizer called +++")
44+
45+
// // typically, this function will check the validity of the incoming token received in the request
46+
47+
// // then it creates and returns a response
48+
// return APIGatewayLambdaAuthorizerPolicyResponse(
49+
// principalId: "John Appleseed",
50+
51+
// // this policy allows the caller to invoke any API Gateway endpoint
52+
// policyDocument: .init(statement: [
53+
// .init(
54+
// action: "execute-api:Invoke",
55+
// effect: .allow,
56+
// resource: "*"
57+
// )
58+
59+
// ]),
60+
61+
// // this is additional context we want to return to the caller
62+
// context: [
63+
// "abc1": "xyz1",
64+
// "abc2": "xyz2",
65+
// ]
66+
// )
67+
// }
68+
69+
//
70+
// This is an example of a simple authorizer that always authorizes the request.
71+
// A simple authorizer returns a yes/no decision and optional context key-value pairs
72+
//
73+
// This code doesn't perform any type of token validation. It should be used as a reference only.
74+
let simpleAuthorizerHandler:
75+
(APIGatewayLambdaAuthorizerRequest, LambdaContext) async throws -> APIGatewayLambdaAuthorizerSimpleResponse = {
76+
(request: APIGatewayLambdaAuthorizerRequest, context: LambdaContext) in
77+
78+
context.logger.debug("+++ Simple Authorizer called +++")
79+
80+
guard let authToken = request.headers["authorization"],
81+
authToken == "Bearer 123"
82+
else {
83+
context.logger.warning("Missing or invalid Authorization header")
84+
return .init(isAuthorized: false, context: [:])
85+
}
86+
87+
return APIGatewayLambdaAuthorizerSimpleResponse(
88+
// this is the authorization decision: yes or no
89+
isAuthorized: true,
90+
91+
// this is additional context we want to return to the caller
92+
context: ["abc1": "xyz1"]
93+
)
94+
}
95+
96+
// create the runtime and start polling for new events.
97+
// in this demo we use the simple authorizer handler
98+
let runtime = LambdaRuntime(body: simpleAuthorizerHandler)
99+
try await runtime.run()

0 commit comments

Comments
 (0)