Fastly Compute@Edge 的 Swift 运行时
使用 executable
模板创建一个新的 swift 包
swift package init --type executable
安装 Compute 运行时
.package(url: "https://github.com/swift-cloud/Compute", from: "3.0.0")
将其添加为目标依赖项
.executableTarget(
name: "MyApp",
dependencies: ["Compute"]
)
将 Swift 应用程序部署到 Fastly 最简单的方法是通过 Swift Cloud。
Swift Cloud 是一个完全托管的平台即服务,用于将 SwiftWasm 应用程序部署到 Fastly。您可以连接您的 Github 帐户,一键部署您的应用程序。
完整的文档仍在积极开发中
https://compute-runtime.swift.cloud/documentation/compute/
以下是在 Compute@Edge 上 Swift 应用程序的样子
import Compute
try await onIncomingRequest { req, res in
let fetchResponse = try await fetch("https://httpbin.org/json", .options(
headers: ["user-agent": "swift-compute-runtime"]
))
let text = try await fetchResponse.text()
try await res.status(200).send(text)
}
Compute@Edge 上的 Swift 得益于令人难以置信的 SwiftWasm 项目,但可能不是您想象的方式。Web Assembly 正在掀起波澜,成为 Web 应用程序开发的新高性能环境,但它也为 Fastly Compute@Edge 等云计算平台提供动力。部署到 Fastly 涉及将您的代码编译为 Web Assembly,然后将其部署到 Fastly 服务。这可以通过 GitHub Actions 完成,但部署代码最绝对简单的方法是通过 Swift Cloud。 Swift Cloud 在 AWS Fargate 实例上构建您的代码,然后使用 Binaryen 优化 WASM 二进制文件。Fastly 服务在后台进行管理,我们使集成 Edge 字典、后端和环境变量等内容变得非常简单。
Compute 包包含一个基于 Vapor 的 routing-kit 的 Express 风格的路由器。以下是一些使用路由器的基本方法
import Compute
let router = Router()
router.get("/status") { req, res in
try await res.status(.ok).send("OK")
}
router.get("/user/:name") { req, res in
let name = req.pathParams["name"] ?? ""
let text = "Hello, \(name)!"
try await res.status(.ok).send(text)
}
try await router.listen()
import Compute
struct User: Codable {
let name: String
}
let router = Router()
router.post("/user") { req, res in
let user = try await req.body.decode(User.self)
try await res.status(.created).send(user)
}
try await router.listen()
如今 WebAssembly 的主要缺点之一是没有标准化的套接字处理方式。因此,SwiftWasm 无法访问某些 Foundation 类,例如 URLSession。这需要每个运行时提供自己的网络层,直到 WASM 规范中引入标准化的线程和套接字模型。
Compute 包提供了 fetch(_ url: String)
函数,用于发送异步 HTTP 请求。该实现很大程度上模仿了 HTML5 fetch()
规范,包括对流式请求和响应体、async/await 和 Codable 支持的完整支持。
重要提示: 为了使用 fetch
,您必须预先定义您将要调用的主机名。例如,如果您正在与 Stripe API 集成,则必须在您的 Fastly 服务中预先定义 api.stripe.com
。Swift Cloud 也使得在创建项目时非常容易定义所有外部源站。我们真诚地希望这是 Fastly 平台的短期限制,并相信他们正在研究一种机制,无需预先定义即可调用任意后端。
let data = try await fetch("https://httpbin.org/json").json()
let res = try await fetch("https://httpbin.org/json", .options(
method: .post,
body: .json(["name": "Andrew"])
))
Compute 包的一个非常强大的功能是能够代理到另一个源站。与单区域源站相比,Fasty 的边缘平台是一个全球分布的 CDN,可提供前所未有的性能。使用 Compute,您可以将功能齐全的 CDN 放在您的源站前面,以执行诸如强制 HTTPS、启用 HTTP/3、提供强大的源站故障转移以及更多操作。
/// req: IncomingRequest, res: OutgoingResponse
let data = try await fetch(req, origin: "https://httpbin.org", .options(
cachePolicy: .ttl(10, staleWhileRevalidate: 30)
))
try await res.proxy(data)
Compute 包提供对 Fastly 缓存 API 的访问,允许您在请求期间缓存和检索任意数据
let data = try await Cache.getOrSet("my-page") {
let res = try await expensivePageRender()
return (res, .ttl(60))
}
try await res
.status(200)
.header(.contentLength, "\(data.contentLength)")
.send(data.body)