这是用于 Hexaville 的应用程序框架层
所有 Hexaville 应用程序都应该使用此框架编写。
import HexavilleFramework
let app = HexavilleFramework()
app.use(RandomNumberGenerateMiddleware())
let router = Router()
router.use(.get, "/") { request, context in
let htmlString = "<html><head><title>Hexaville</title></head><body>Welcome to Hexaville!</body></html>"
return Response(headers: ["Content-Type": "text/html"], body: htmlString)
}
app.use(router)
try app.run()
let app = HexavilleFramework()
let router = Router()
router.use(.get, "/hello") { response, context in
return Response(body: "Hello")
}
app.use(router)
let app = HexavilleFramework()
let router = Router()
router.use(.get, middlewares: [RandomNumberGenerateMiddleware()], "/hello") { response, context in
return Response(body: "Random number is \(context["randomNumber"])")
}
app.use(router)
您可以创建自己的中间件来遵循 Middleware
协议。
enum JWTAuthenticationMiddleware {
case authrozationHeaderIsMissing
}
struct JWTAuthenticationMiddleware: Middleware {
func respond(to request: Request, context: ApplicationContext) throws -> Chainer {
guard let jwtString = request.headers["Authorization"] else {
throw JWTAuthenticationMiddleware.authrozationHeaderIsMissing
}
let jwt = try JWT.decode(jwtString)
context.memory["JWT"] = jwt
return .next(request)
}
}
app.use(JWTAuthenticationMiddleware())
ApplicationContext 是请求的共享存储。
memory
属性用于在中间件和路由器之间共享值。
struct FooMiddleware: Middleware {
func respond(to request: Request, context: ApplicationContext) throws -> Chainer {
context.memory["Foo"] = "Bar"
return .next(request)
}
}
app.use(.get, middlewares: [FooMiddleware()], "/foo") { request, context in
print(context["Foo"]) // Bar
}
在某些中间件中,您可能想要预设响应头,例如 Set-Cookie
。通过将 HTTP 标头预设到 responseHeaders
属性中,标头值将自动添加到框架端的实际响应中。
这是一个示例。
struct CookieSetMiddleware: Middleware {
func respond(to request: Request, context: ApplicationContext) throws -> Chainer {
context.responseHeaders["Set-Cookie"] = "vaild cookie value"
return .next(request)
}
}
app.use(.get, middlewares: [FooMiddleware()], "/foo") { request, context in
return Response(body: "OK")
}
HTTP/1.1 200
Set-Cookie: vaild cookie value
OK
session
属性用于应用程序中使用的数据持久化。 有关详细信息,请参阅 会话 (Session)。
HexavilleFramework 通过 SessionMiddleware
提供会话机制。 您可以创建自己的 SessionStore 来遵循 SessionStoreProvider
协议。
捆绑的会话存储是 MemoryStore
。
let session = SessionMiddleware(
cookieAttribute: CookieAttribute(
expiration: 3600,
httpOnly: true,
secure: false
),
store: MemoryStore()
)
app.use(session)
app.use { request, context in
// add value to session(memory)
context.session["user"] = User(name: "Luke", age: 25).serializeToJSONString()
}
var router = Router()
// take value from context.session
router.use(.get, "/") { request, context in
return Response(body: context.session["user"]!)
}
您可以捕获会话中抛出的所有错误,使用 catch
错误处理程序。 在 catch 闭包中,确定错误响应的最佳方法是针对 Error
进行模式匹配。
let app = HexavilleFramework()
app.use(.....)
app.catch { error in
switch error {
case FooError.notFound:
return Response(status: .notFound)
case JWTAuthenticationMiddleware.authrozationHeaderIsMissing:
return Response(status: .unauthorized)
default:
return Response(status: .internalServerError)
}
}
try app.run()
请参阅 Hexaville 文档
您可以使用内置的 Web 服务器和 serve
命令来调试您的应用程序。
YourApplication/.build/debug/YourApplication serve
# => Hexaville Builtin Server started at 0.0.0.0:3000
HexavilleFramework 是在 MIT 许可证下发布的。 有关详细信息,请参阅 LICENSE 文件。