Aoxiang

Aoxiang (翱翔) 是一个轻量级的 HTTP 服务器库,使用 Swift 编写,适用于 iOS/macOS/tvOS。

特性

Hello World

import Aoxiang

let server = HTTPServer()

server.get("/") { req, res in
    res.send("Hello World!")
}

try server.start(8080)

然后在浏览器中访问 https://:8080/ 以查看结果。

基本路由

路由是指应用程序的端点(URI)如何响应客户端请求。 您可以使用 HTTPServer 实例的方法来定义路由,这些方法对应于 HTTP 方法;例如,get() 用于处理 GET 请求,post() 用于处理 POST 请求。

以下示例说明了如何定义简单的路由。

在主页上响应 Hello World!

server.get("/") { req, res in
    res.send("hello Aoxiang!")
}

响应主页上的 POST 请求

server.post("/") { req, res in
    res.send("Got a POST request")
}

响应到 /user 路由的 PUT 请求

server.put("/user") { req, res in
    res.send("Got a PUT request at /user")
}

响应到 /user 路由的 DELETE 请求

server.delete("/user") { req, res in
    res.send("Got a DELETE request at /user")
}

Async/Await

Aoxiang 支持 async/await 来处理异步操作,这使您的代码更具可读性,更易于维护。

server.get("/async") { req, res async in
    let user = await readUserInfo()
    res.send(user.name)
}

中间件

中间件函数是可以访问 HTTP 请求(req)和响应(res)对象以及应用程序的请求-响应周期中的下一个函数。 next 函数是路由器中的一个函数,当被调用时,它会执行当前中间件之后的中间件。

中间件函数可以执行以下任务

您可以在 Web 应用程序中使用中间件来实现许多目的,例如

Aoxiang 支持类似 Express 的中间件。 您可以使用 use() 将中间件添加到您的服务器。

此示例显示了一个没有挂载路径的中间件函数。 每次应用程序收到请求时,都会执行该函数。

server.use { req, res, next in
    print("Time: \(Date())")
    next()
}

您也可以使用 HTTPMiddleware 来实现中间件。

class TimeMiddleware: HTTPMiddleware {
    override func handle(_ req: HTTPRequest, _ res: HTTPResponse, next: @escaping () -> Void) {
        print("Time: \(Date())")
        next()
    }
}

server.use(TimeMiddleware())

中间件加载的顺序很重要:首先加载的中间件函数也会首先执行。

分块流式传输

Aoxiang 开箱即用地支持 HTTP 分块传输编码。 您可以使用 write() 将分块数据发送到客户端,并使用 end() 结束响应。

server.get("/stream") { _, res in
    res.write("hi,")
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
        res.write("Aoxiang.")
        res.end()
    }
}

SSE(服务器发送事件)

Aoxiang 开箱即用地支持 SSE(服务器发送事件)。 您可以使用 sendEvents() 获取一个 EventSource 并将事件发送给客户端。 不要忘记调用 close() 关闭连接。

server.get("/sse") { req, res in
    let target = res.sendEvents()
    target.dispatchMessage("SSE Response:")
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
        target.dispatchMessage("chunk 1")
        target.close()
    }
}

更改响应头

Aoxiang 提供了一个 headers 属性来帮助您更改响应头,您可以在调用 send()write() 之前设置它。

此示例显示了如何设置单个标头

server.post("/send") { req, res in
    res.headers["Access-Control-Allow-Origin"] = "*"
    // ...
}

此示例显示了如何设置 HTTP 状态代码

server.post("/send") { req, res in
    res.statusCode = 404
    // ...
}

对于更多自定义,您可以查看 HTTPResponse 类。

安装

要求

Swift 包管理器

或将以下内容添加到您的 Package.swift 文件中

dependencies: [
    .package(url: "https://github.com/isaced/Aoxiang.git", .upToNextMajor(from: "1.0.0"))
]

常见问题解答

为什么命名为 Aoxiang?

Aoxiang (翱翔) 在中文中意为“翱翔”。 我希望这个库可以帮助您轻松地构建自己的轻量级 Web 服务器。

res.send() vs res.write()

联系方式

Twitter 上关注并联系我。 如果您发现问题,请开启一个 issue。 也非常欢迎 Pull Request。

许可证

Aoxiang 在 MIT 许可证下发布。 有关详细信息,请参见 LICENSE。