Skip to content

Commit d311397

Browse files
Merge pull request #2 from swift-server-community/sebsto/openapi
initial commit for openapi example
2 parents 54e0978 + f3dcf41 commit d311397

18 files changed

+440
-1
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
__pycache__/
22
*.__pyc
33
.DS_Store
4+
.build

Diff for: cookiecutter.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
"path": "templates/scheduler-to-lambda",
2020
"title": "Scheduler to Lambda",
2121
"description": "Scheduled events to Lambda function integration"
22-
}
22+
},
23+
"openapi-to-lambda": {
24+
"path": "templates/openapi-to-lambda",
25+
"title": "OpenAPI definition to Lambda",
26+
"description": "An OpenAPI definition to generate the Lambda function (with API Gateway)"
27+
}
2328
}
2429
}

Diff for: templates/openapi-to-lambda/cookiecutter.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"project_name": "StockQuote OpenApi to Swift Lambda",
3+
"__project_name": "{{ cookiecutter.project_name|lower|replace(' ', '-') }}",
4+
"__architecture": "{{ 'x86_64'|architecture }}",
5+
"_copy_without_render": [".gitignore"],
6+
"_template_name": "OpenApi to Lambda",
7+
"_runtime": "Swift 5.10.0",
8+
"_swift_tools_version": "5.10.0",
9+
"_aws_swift_sdk_version": "0.45.0",
10+
"__project_dir": "{{ 'Change this path'|get_abs_path }}/{{ cookiecutter.__project_name }}",
11+
"_extensions": [
12+
"local_extensions.architecture",
13+
"local_extensions.get_abs_path"
14+
]
15+
}

Diff for: templates/openapi-to-lambda/doc/INFO.md

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# OpenAPI to Lambda SAM template
2+
3+
This templates allows developers to start with an OpenAPI definition of the REST service they want to create.
4+
5+
The swift OpenAPI generator plugin generates data types and server stubs at each `swift build` command. This ensures your Swift code stays in sync with your OpenAPI definition.
6+
7+
When deploying this project on your AWS account, it created an Amazon API Gateway configured as pass-through. The API Gateway forwards all API calls to your Lambda function.
8+
9+
## How to use this template?
10+
11+
First, clone the template.
12+
13+
```sh
14+
sam init \
15+
--location https://github.com/swift-server-community/aws-lambda-swift-sam-template/tree/main/templates/openapi-to-lambda \
16+
--no-interactive \
17+
--no-input \
18+
--name <your project name>
19+
```
20+
21+
## Testing a template locally
22+
23+
Testing a template locally
24+
You can create a buildable and deployable project folder from a local template using the below command. The `<project_name>` can be whatever you want your project to be called, and `<path/to/init_template>` should point to the existing folder that contains the template.
25+
26+
Command:
27+
28+
```sh
29+
sam init --location <path/to/init_template> \
30+
--no-input \
31+
--name <project_name>
32+
```
33+
34+
For example:
35+
36+
```sh
37+
sam init \
38+
--location /Users/myuser/code/aws-lambda-swift-sam-template/openapi-t-lambda \
39+
--name StockQuoteApi
40+
```
41+
42+
## Learn more
43+
44+
- [Swift OpenAPI Generator](https://github.com/apple/swift-openapi-generator)
45+
- [Swift OpenAPI Transport for AWS Lambda](https://github.com/swift-server/swift-openapi-lambda)

Diff for: templates/openapi-to-lambda/doc/dark.webp

27.1 KB
Binary file not shown.

Diff for: templates/openapi-to-lambda/doc/illustrations.pptx

164 KB
Binary file not shown.

Diff for: templates/openapi-to-lambda/doc/light.webp

25.3 KB
Binary file not shown.

Diff for: templates/openapi-to-lambda/local_extensions.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#===----------------------------------------------------------------------===//
2+
#
3+
# This source file is part of the AWS Lambda Swift
4+
# VSCode extension open source project.
5+
#
6+
# Copyright (c) 2024, the VSCode AWS Lambda Swift extension 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 VSCode AWS Lambda Swift project authors
11+
#
12+
# SPDX-License-Identifier: Apache-2.0
13+
#
14+
#===----------------------------------------------------------------------===//
15+
16+
import platform
17+
import os
18+
from cookiecutter.utils import simple_filter
19+
20+
@simple_filter
21+
def architecture(v):
22+
arch = platform.machine().lower()
23+
if 'aarch' in arch or 'arm' in arch:
24+
return 'arm64'
25+
else:
26+
return v
27+
28+
@simple_filter
29+
def get_abs_path(v):
30+
if os.getcwd():
31+
return os.getcwd()
32+
else:
33+
return v
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.DS_Store
2+
.aws-sam/
3+
*/build/*
4+
/.build
5+
/Packages
6+
xcuserdata/
7+
DerivedData/
8+
.swiftpm/configuration/registries.json
9+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
10+
.netrc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#===----------------------------------------------------------------------===//
2+
#
3+
# This source file is part of the AWS Lambda Swift
4+
# VSCode extension open source project.
5+
#
6+
# Copyright (c) 2024, the VSCode AWS Lambda Swift extension 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 VSCode AWS Lambda Swift project authors
11+
#
12+
# SPDX-License-Identifier: Apache-2.0
13+
#
14+
#===----------------------------------------------------------------------===//
15+
16+
FROM swift:amazonlinux2
17+
18+
RUN yum -y install openssl-devel
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#===----------------------------------------------------------------------===//
2+
#
3+
# This source file is part of the AWS Lambda Swift
4+
# VSCode extension open source project.
5+
#
6+
# Copyright (c) 2024, the VSCode AWS Lambda Swift extension 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 VSCode AWS Lambda Swift project authors
11+
#
12+
# SPDX-License-Identifier: Apache-2.0
13+
#
14+
#===----------------------------------------------------------------------===//
15+
16+
BUILD_DIR := {{ cookiecutter.__project_dir }}/.aws-sam/build
17+
BUILD_FLAG := $(BUILD_DIR)/build_complete.flag
18+
DOCKER_IMAGE := swift-lambda-builder-workaround
19+
20+
.PHONY: build-%
21+
22+
build-%:
23+
@if [ ! -f $(BUILD_FLAG) ]; then \
24+
echo "Building All Lambdas..."; \
25+
docker inspect $(DOCKER_IMAGE) >/dev/null 2>&1 || docker build -t $(DOCKER_IMAGE) .; \
26+
swift package --disable-sandbox plugin archive --base-docker-image $(DOCKER_IMAGE) --disable-docker-image-update --output-path $(BUILD_DIR); \
27+
echo "Build for all Lambdas complete."; \
28+
touch $(BUILD_FLAG); \
29+
fi
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// swift-tools-version: {{ cookiecutter._swift_tools_version }}
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
//===----------------------------------------------------------------------===//
5+
//
6+
// This source file is part of the AWS Lambda Swift
7+
// VSCode extension open source project.
8+
//
9+
// Copyright (c) 2024, the VSCode AWS Lambda Swift extension project authors.
10+
// Licensed under Apache License v2.0.
11+
//
12+
// See LICENSE.txt for license information
13+
// See CONTRIBUTORS.txt for the list of VSCode AWS Lambda Swift project authors
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
//
17+
//===----------------------------------------------------------------------===//
18+
19+
import PackageDescription
20+
21+
let package = Package(
22+
name: "QuoteService",
23+
platforms: [
24+
.macOS(.v13), .iOS(.v15), .tvOS(.v15), .watchOS(.v6),
25+
],
26+
products: [
27+
.executable(name: "QuoteService", targets: ["QuoteService"]),
28+
],
29+
dependencies: [
30+
.package(url: "https://github.com/apple/swift-openapi-generator.git", from: "1.0.0"),
31+
.package(url: "https://github.com/apple/swift-openapi-runtime.git", from: "1.0.0"),
32+
.package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "1.0.0-alpha.1"),
33+
.package(url: "https://github.com/swift-server/swift-aws-lambda-events.git", from: "0.2.0"),
34+
.package(url: "https://github.com/swift-server/swift-openapi-lambda.git", from: "0.1.1")
35+
],
36+
targets: [
37+
.executableTarget(
38+
name: "QuoteService",
39+
dependencies: [
40+
.product(name: "OpenAPIRuntime",package: "swift-openapi-runtime"),
41+
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
42+
.product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"),
43+
.product(name: "OpenAPILambda",package: "swift-openapi-lambda"),
44+
],
45+
path: "Sources",
46+
resources: [
47+
.copy("openapi.yaml"),
48+
.copy("openapi-generator-config.yaml")
49+
],
50+
plugins: [
51+
.plugin(
52+
name: "OpenAPIGenerator",
53+
package: "swift-openapi-generator"
54+
)
55+
]
56+
)
57+
]
58+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# {{ cookiecutter.project_name }}
2+
3+
This template creates an API based on an OpenAPI definition document. It implements the API with an AWS Lambda function and an Amazon API Gateway.
4+
5+
## Usage
6+
7+
### How to Use
8+
9+
1. **Build Project**: Navigate to the project directory and run `sam build` to build the Lambda function.
10+
2. **Deploy Project**: Execute `sam deploy --guided` to deploy the project to AWS. Follow the prompts to configure the deployment settings.
11+
3. **Test API**: Use the provided API endpoint to test the API functionality.
12+
13+
### How to Build
14+
15+
Run the following command to build the Swift project:
16+
17+
```bash
18+
sam build
19+
```
20+
21+
### How to Deploy
22+
23+
Deploy the project to AWS using the following command:
24+
25+
```bash
26+
sam deploy --guided
27+
```
28+
29+
During the guided deployment process, accept each default prompt except for the authorization:
30+
31+
```bash
32+
StockQuoteAPI may not have authorization defined, Is this okay? [y/N]:
33+
```
34+
make sure to input "y" to proceed.
35+
36+
### How to Test
37+
38+
#### Locally
39+
40+
To test the Lambda function locally, you can use the following command:
41+
42+
```bash
43+
sam local invoke StockQuoteAPI --event events/GetQuote.json
44+
```
45+
46+
#### After Deployment (using the API)
47+
48+
After a successful deployment, you will receive CloudFormation outputs from the deployed stack. Among these outputs, you will find the API Gateway endpoint URL for your application. You can use tools like cURL or Postman to make requests to this API endpoint.
49+
50+
```bash
51+
Outputs
52+
----------------------------------------------------------------------------------------
53+
Key SwiftAPIEndpoint
54+
Description API Gateway endpoint URL for your application
55+
Value https://[your-api-id].execute-api.[your-aws-region].amazonaws.com
56+
----------------------------------------------------------------------------------------
57+
```
58+
59+
### How to Delete
60+
61+
To delete the deployed resources, you can use the AWS Management Console or run the following command:
62+
63+
```bash
64+
sam delete
65+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import Foundation
2+
import OpenAPIRuntime
3+
import OpenAPILambda
4+
5+
@main
6+
struct QuoteServiceImpl: APIProtocol, OpenAPILambdaHttpApi {
7+
8+
init(transport: OpenAPILambdaTransport) throws {
9+
try self.registerHandlers(on: transport)
10+
}
11+
12+
func getQuote(_ input: Operations.getQuote.Input) async throws -> Operations.getQuote.Output {
13+
14+
let symbol = input.path.symbol
15+
16+
// generate the response with random numbers.
17+
// adjust for your own logic
18+
let price = Components.Schemas.quote(
19+
symbol: symbol,
20+
price: Double.random(in: 100..<150).rounded(),
21+
change: Double.random(in: -5..<5).rounded(),
22+
changePercent: Double.random(in: -0.05..<0.05),
23+
volume: Double.random(in: 10000..<100000).rounded(),
24+
timestamp: Date())
25+
26+
return .ok(.init(body: .json(price)))
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
generate:
2+
- types
3+
- server
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
openapi: 3.1.0
2+
info:
3+
title: StockQuoteService
4+
version: 1.0.0
5+
6+
components:
7+
schemas:
8+
quote:
9+
type: object
10+
properties:
11+
symbol:
12+
type: string
13+
price:
14+
type: number
15+
change:
16+
type: number
17+
changePercent:
18+
type: number
19+
volume:
20+
type: number
21+
timestamp:
22+
type: string
23+
format: date-time
24+
25+
paths:
26+
/stocks/{symbol}:
27+
get:
28+
summary: Get the latest quote for a stock
29+
operationId: getQuote
30+
parameters:
31+
- name: symbol
32+
in: path
33+
required: true
34+
schema:
35+
type: string
36+
tags:
37+
- stocks
38+
responses:
39+
200:
40+
description: OK
41+
content:
42+
application/json:
43+
schema:
44+
$ref: '#/components/schemas/quote'
45+
400:
46+
description: Bad Request
47+
404:
48+
description: Not Found

0 commit comments

Comments
 (0)