{"id":15038803,"url":"https://github.com/noppoman/hexavilleframework","last_synced_at":"2025-12-29T07:07:22.814Z","repository":{"id":63919322,"uuid":"91553422","full_name":"noppoMan/HexavilleFramework","owner":"noppoMan","description":"An Application Framework Layer for Hexaville","archived":false,"fork":false,"pushed_at":"2019-09-27T13:50:05.000Z","size":88,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-20T22:18:35.976Z","etag":null,"topics":["hexaville","server-side-swift","serverless","swift4"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/noppoMan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-17T08:39:40.000Z","updated_at":"2020-05-19T09:07:31.000Z","dependencies_parsed_at":"2023-01-14T14:00:25.072Z","dependency_job_id":null,"html_url":"https://github.com/noppoMan/HexavilleFramework","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noppoMan%2FHexavilleFramework","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noppoMan%2FHexavilleFramework/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noppoMan%2FHexavilleFramework/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noppoMan%2FHexavilleFramework/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/noppoMan","download_url":"https://codeload.github.com/noppoMan/HexavilleFramework/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243428434,"owners_count":20289317,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hexaville","server-side-swift","serverless","swift4"],"created_at":"2024-09-24T20:40:17.076Z","updated_at":"2025-12-29T07:07:22.751Z","avatar_url":"https://github.com/noppoMan.png","language":"Swift","readme":"# HexavilleFramework\nThis is Application Framework Layer for [Hexaville](https://github.com/noppoMan/Hexaville)\n\nAll Hexaville applications should be written in this framework.\n\n## Table of contents\n\n* [Routing](#routing)\n* [Middleware](#middleware)\n* [ApplicationContext](#applicationcontext)\n* [Session](#session)\n* [Error Handling](#error-handling)\n* [How to Deploy](#how-to-deploy)\n* [Builtin Web Server](#builtin-web-server)\n\n\n## Usage\n\n```swift\nimport HexavilleFramework\n\nlet app = HexavilleFramework()\n\napp.use(RandomNumberGenerateMiddleware())\n\nlet router = Router()\n\nrouter.use(.get, \"/\") { request, context in\n    let htmlString = \"\u003chtml\u003e\u003chead\u003e\u003ctitle\u003eHexaville\u003c/title\u003e\u003c/head\u003e\u003cbody\u003eWelcome to Hexaville!\u003c/body\u003e\u003c/html\u003e\"\n    return Response(headers: [\"Content-Type\": \"text/html\"], body: htmlString)\n}\n\napp.use(router)\n\ntry app.run()\n```\n\n## Routing\n\n### Basic Routing\n\n```swift\nlet app = HexavilleFramework()\n\nlet router = Router()\n\nrouter.use(.get, \"/hello\") { response, context in\n    return Response(body: \"Hello\")\n}\n\napp.use(router)\n```\n\n### Routing with Middleware\n\n```swift\nlet app = HexavilleFramework()\n\nlet router = Router()\n\nrouter.use(.get, middlewares: [RandomNumberGenerateMiddleware()], \"/hello\") { response, context in\n    return Response(body: \"Random number is \\(context[\"randomNumber\"])\")\n}\n\napp.use(router)\n```\n\n## Middleware\n\nYou can create your own Middlewares to confirm `Middleware` protocol.\n\n```swift\nenum JWTAuthenticationMiddleware {\n    case authrozationHeaderIsMissing\n}\n\nstruct JWTAuthenticationMiddleware: Middleware {\n    func respond(to request: Request, context: ApplicationContext) throws -\u003e Chainer {\n        guard let jwtString = request.headers[\"Authorization\"] else {\n            throw JWTAuthenticationMiddleware.authrozationHeaderIsMissing\n        }\n        \n        let jwt = try JWT.decode(jwtString)\n        \n        context.memory[\"JWT\"] = jwt\n        \n        return .next(request)\n    }\n}\n\napp.use(JWTAuthenticationMiddleware())\n```\n\n## ApplicationContext\n\nApplicationContext is the shared storage for the request. \n\n#### Available properties\n\n* memory\n* responseHeaders\n* session\n\n### memory\n\n`memory` property is used for share value between Middlewares and the Router.\n\n```swift\nstruct FooMiddleware: Middleware {\n    func respond(to request: Request, context: ApplicationContext) throws -\u003e Chainer {\n        context.memory[\"Foo\"] = \"Bar\"\n        return .next(request)\n    }\n}\n\napp.use(.get, middlewares: [FooMiddleware()], \"/foo\") { request, context in\n    print(context[\"Foo\"]) // Bar\n}\n```\n\n### responseHeaders\n\nIn the some middlewares, You'll want to preset response headers, sunch as `Set-Cookie`. By preseting HTTP headers into the `responseHeaders` property, the header values are automatically adedd to the actual response on the Framework side.\n\nHere is an example.\n\n```swift\nstruct CookieSetMiddleware: Middleware {\n    func respond(to request: Request, context: ApplicationContext) throws -\u003e Chainer {\n        context.responseHeaders[\"Set-Cookie\"] = \"vaild cookie value\"\n        return .next(request)\n    }\n}\n\napp.use(.get, middlewares: [FooMiddleware()], \"/foo\") { request, context in\n    return Response(body: \"OK\")\n}\n```\n\n#### response\n```\nHTTP/1.1 200\n\nSet-Cookie: vaild cookie value\n\nOK\n```\n\n### session\n\n`session` property is used for data persistence that use in the application.\nSee [Session](#session) for the detail.\n\n## Session\n\nHexavilleFramework provides Session Mechanism by `SessionMiddleware`. You can create your own SessionStore to conform `SessionStoreProvider` protocol.\n\nBundled Sesssion Store is `MemoryStore`.\n\n#### Available Session Stores\n\n* MemoryStore: Bundled Session Store\n* [DynamoDBSessionStore](https://github.com/Hexaville/DynamodbSessionStore)\n* [RedisSessionStore](https://github.com/Hexaville/RedisSessionStore)\n\n### Usage\n\n```swift\nlet session = SessionMiddleware(\n    cookieAttribute: CookieAttribute(\n        expiration: 3600,\n        httpOnly: true,\n        secure: false\n    ),\n    store: MemoryStore()\n)\n\napp.use(session)\n\napp.use { request, context in\n    // add value to session(memory)\n    context.session[\"user\"] = User(name: \"Luke\", age: 25).serializeToJSONString()\n}\n\nvar router = Router()\n\n// take value from context.session\nrouter.use(.get, \"/\") { request, context in\n    return Response(body: context.session[\"user\"]!)\n}\n```\n\n## Error handling\n\nYou can catch all of the errors that are throwed in the session with `catch` error handler.\nIn the catch closure, the best way of the determining error response is pattern matching for the `Error`.\n\n```swift\nlet app = HexavilleFramework()\n\napp.use(.....)\n\napp.catch { error in\n    switch error {\n    case FooError.notFound:\n        return Response(status: .notFound)\n    case JWTAuthenticationMiddleware.authrozationHeaderIsMissing:\n        return Response(status: .unauthorized)\n    default:\n        return Response(status: .internalServerError)\n    }\n}\n\ntry app.run()\n```\n\n## How to deploy?\nSee the Hexaville [Documentation](https://github.com/noppoMan/Hexaville)\n\n## Builtin Web Server\n\nYou can debug your application with the builtin web server with `serve` command.\n\n```sh\nYourApplication/.build/debug/YourApplication serve\n# =\u003e Hexaville Builtin Server started at 0.0.0.0:3000\n```\n\n## License\n\nHexavilleFramework is released under the MIT license. See LICENSE for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoppoman%2Fhexavilleframework","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnoppoman%2Fhexavilleframework","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoppoman%2Fhexavilleframework/lists"}