swift-lambda-runtime

⚠️此项目是未维护的旧代码,从未达到 1.0 版本。它已被 swift-server/swift-aws-lambda-runtime 取代,后者包含更快、更优化的 AWS Lambda 运行时,具有更好的 API,可以满足更多需求。

Swift 5.2 github-actions codecov

一个基于 SwiftNIO 的 AWS Lambda Swift 运行时,带有一些即用型的 AWS 事件。 它旨在与 Swift on Amazon Linux 项目一起使用,该项目确保 Swift 可执行文件可以在 Amazon Linux 上运行。

一个 APIGateway Lambda 看起来像这样

import LambdaRuntime
import NIO

let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
defer { try! group.syncShutdownGracefully() }

struct Input: Codable {
  let name: String
}

struct Greeting: Codable {
  let greeting: String
}

let handler = APIGateway.handler() { (request, ctx) in
  do {
    let payload = try request.decodeBody(Input.self)

    let response = try APIGateway.Response(
      statusCode: .ok,
      payload: Greeting(greeting: "Hello \(payload.name)"))
  
    return ctx.eventLoop.makeSucceededFuture(response)
  }
  catch {
    return ctx.eventLoop.makeFailedFuture(error)
  }
}

let runtime = try Runtime.createRuntime(eventLoopGroup: group, handler: handler)
defer { try! runtime.syncShutdown() }
try runtime.start().wait()

如果您想在 APIGateway 后面的 Lambda 上运行您的 Vapor 应用程序,请查看 vapor-lambda-runtime,它构建在此包之上。

状态

替代方案:还有另一个在 AWS-Lambda 中运行 Swift 的项目:Swift-Sprinter

创建并运行您的第一个 Swift Lambda

这应该可以帮助您开始在 AWS Lambda 上使用 Swift。重点主要放在 AWS 控制台上,因为这是最容易开始的方法。当然,您可以使用 aws-clisam-cliserverless-frameworkcloudformation 或您在每个步骤中喜欢的任何工具。 我甚至鼓励您在生产环境这样做。 没有人喜欢点击式架构。 🤯 如果您正在寻找示例,请查看 sam-templateTodoBackend 示例中。

注意:以下说明记录于 2019 年 12 月 19 日,此后 GUI 可能已更改。 如果您看到不同的 GUI,请随时提出问题。

此处使用的 Swift 版本是 5.2.1。 您可以在 Amazonlinux 上查看可用的 Swift 版本 这里。 如果对您有效,您可能需要使用更高版本!

步骤 1:开发您的 lambda

创建一个新的 Swift Package Manager 项目。 为了简单起见,我们将只关注用 Lambda 函数对数字进行平方运算。

$ mkdir SquareNumbers
$ cd SquareNumbers
$ swift package init --type executable

从这里开始的最简单方法是将新创建的 Package.swift 拖到 Xcode 上,以在 Xcode 中打开 Swift 包。

接下来,我们将需要包含 LambdaRuntimeSwiftNIO 作为依赖项。 为此,请打开 Package.swift 并对其进行修改,使其看起来像这样

// swift-tools-version:5.2
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
  name: "SquareNumber",
  dependencies: [
    .package(url: "https://github.com/fabianfett/swift-lambda-runtime.git", .upToNextMajor(from: "0.6.0")),
    .package(url: "https://github.com/apple/swift-nio", .upToNextMajor(from: "2.13.0")),
  ],
  targets: [
    .target(
      name: "SquareNumber",
      dependencies: [
        .product(name: "LambdaRuntime", package: "swift-lambda-runtime"),
        .product(name: "NIO", package: "swift-nio"),
      ]
    ),
  ]
)

然后打开您的 main.swift 并创建您的函数。 如前所述,在此示例中,我们只想对数字进行平方,尽管您的函数可以执行任何您想要的操作。

import LambdaRuntime
import NIO

struct Input: Codable {
  let number: Double
}

struct Output: Codable {
  let result: Double
}

func squareNumber(input: Input, context: Context) -> EventLoopFuture<Output> {
  let squaredNumber = input.number * input.number
  return context.eventLoop.makeSucceededFuture(Output(result: squaredNumber))
}

let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
defer { try! group.syncShutdownGracefully() }

do {
  let runtime = try Runtime.createRuntime(
    eventLoopGroup: group, 
    handler: Runtime.codable(squareNumber))

  defer { try! runtime.syncShutdown() }
  
  try runtime.start().wait()
}
catch {
  print("\(error)")
}

步骤 3:构建您的 lambda

您的 lambda 需要为 Amazon Linux 环境构建。 为此,我们使用 Docker 编译 Lambda。 请注意,您需要使用与运行 lambda 相同的 Swift 版本来编译 lambda。 ABI 稳定性在 Linux 上不存在

为此,我们首先需要构建一个开发 Docker 镜像,以便在 Linux 上编译您的代码。 创建一个 Docker 文件并包含以下代码

ARG SWIFT_VERSION=5.2.1
FROM fabianfett/amazonlinux-swift:$SWIFT_VERSION-amazonlinux2

# needed to do again after FROM due to docker limitation
ARG SWIFT_VERSION

RUN yum -y update && \
  yum -y install zlib-devel kernel-devel gcc-c++ openssl-devel

要创建您的 Docker 镜像,请运行

docker build --build-arg SWIFT_VERSION=5.2.1 -t lambda-swift-dev:5.2.1 .

现在,我们可以使用新镜像编译我们的 lambda。

# build your lambda in the linux environment 
$ docker run --rm --volume "$(pwd)/:/src" --workdir "/src/" lambda-swift-dev:5.2.1 swift build -c release

这将在您的 ./build/release 文件夹中创建一个 SquareNumber 可执行文件。 让我们获取该可执行文件并将其重命名为 bootstrap

# copy your executable to your local folder and rename it to bootstrap
$ cp .build/release/$(EXAMPLE_EXECUTABLE) ./bootstrap

最后:我们需要在上传到 AWS 之前压缩 bootstrap。

# zip your bootstrap
$ zip -j lambda.zip ./bootstrap

步骤 4:在 AWS 上创建您的 lambda

打开您的 AWS 控制台并导航至 Lambda。 在侧边导航栏中选择“函数”,然后单击右上角的“创建函数”。 给您的函数命名。 我将选择“SquareNumbers”并选择运行时“提供您自己的 bootstrap”。

您会看到一个看起来像这样的屏幕。

Create your function

首先,我们需要选择我们的 Swift 运行时。 我们通过单击屏幕中央函数名称下方的“层”来完成此操作。 屏幕的下部发生变化,我们可以看到中央的“添加层”按钮。 让我们单击该按钮。 在下一个屏幕上,我们需要选择“提供图层版本 ARN”,然后在此处输入适合我们用于编译的 Swift 版本的 ARN。 对于 Swift 5.2.1,它是 arn:aws:lambda:<region>:426836788079:layer:Swift:12。 不要忘记将 <region> 替换为您所在的 AWS 区域标识符。 接下来,我们单击“添加”。

Add the Swift layer to your Function

现在,您应该在我们的函数下方看到一个图层。 接下来,我们单击函数名称。 您应该在屏幕的下部看到“函数代码”部分。 在“代码条目类型”中选择“上传 zip 文件”。 单击“上传”并选择您的 lambda.zip。 在“处理程序”字段中,您可以填写任何内容(至少一个字符),因为此字段未被我们的运行时使用。接下来,单击“保存”。

Upload your lambda code

步骤 5:调用您的 lambda

剩下的唯一事情就是调用您的 lambda。 选择“测试”(在右上角)并将您的测试有效负载更改为您想要提供给您的函数的任何 json。 因为我想要平方的数字,所以我的如下

{
  "number": 3
}

由于 AWS 希望一遍又一遍地重复使用您的事件进行测试,因此您需要为您的测试事件命名。 我的是“Number3”。 单击“保存”,您可以再次单击“测试”,这次您的 lambda 将被执行。 如果一切顺利,您应该看到如下屏幕

The lambda invocation is a success!

下一步是什么?

太棒了! 你已经做到了。 在我看来,您现在应该熟悉 AWS Lambda 的一些工具。

Lambda 部署/测试工具

它可能是 serverless 或 aws-sam,因为没有人愿意或应该仅通过在 AWS 控制台中单击来构建 Lambda 服务。 TodoList 示例是 使用 aws-sam 设置。 如果您需要更多关于如何开始使用 aws-sam 的帮助,请通过打开 GitHub 问题来联系。

aws-sdk

有两个项目为您提供 API 来与 AWS 资源进行交互。

日志记录

如果要在 lambda 内部记录某些内容,可以使用 Context 类上的 logger 属性logger 基于 swift-log,因此应该与许多其他服务器端 Swift 项目兼容。 默认情况下,RequestId 作为元数据公开。 可以在 此处 找到示例。

EventLoop

可以通过 Context 类上的 eventLoop 属性 访问执行函数的 EventLoop。 可以在 此处 找到示例。

贡献

请随意并鼓励您为 swift-lambda-runtime 做出贡献。 swift-lambda-runtime 的当前版本在准备好用于生产用途之前还有很长的路要走,并且始终欢迎帮助。

如果您发现错误、有建议或需要帮助入门,请打开 Issue 或 PR。 如果您使用此包,我将感谢分享您的经验。

目前重点关注的领域

致谢