{"id":27404562,"url":"https://github.com/gavrilaf/seagull","last_synced_at":"2025-10-29T16:22:35.439Z","repository":{"id":50207250,"uuid":"131469069","full_name":"gavrilaf/Seagull","owner":"gavrilaf","description":"Swift web framework","archived":false,"fork":false,"pushed_at":"2022-12-08T02:07:25.000Z","size":134,"stargazers_count":3,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-15T03:18:54.675Z","etag":null,"topics":["http","router","swift","swift-nio","web-framework"],"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/gavrilaf.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":"2018-04-29T05:39:59.000Z","updated_at":"2018-10-31T03:09:26.000Z","dependencies_parsed_at":"2022-09-24T08:01:18.382Z","dependency_job_id":null,"html_url":"https://github.com/gavrilaf/Seagull","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/gavrilaf/Seagull","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavrilaf%2FSeagull","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavrilaf%2FSeagull/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavrilaf%2FSeagull/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavrilaf%2FSeagull/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gavrilaf","download_url":"https://codeload.github.com/gavrilaf/Seagull/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavrilaf%2FSeagull/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259802125,"owners_count":22913570,"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":["http","router","swift","swift-nio","web-framework"],"created_at":"2025-04-14T05:39:15.051Z","updated_at":"2025-10-29T16:22:35.340Z","avatar_url":"https://github.com/gavrilaf.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Seagull\n\nSwift web framework based on the swift-nio.\n\nThe Seagull main idea is creating a minimum web framework. Routing and some data processing helpers - nothing else. Seagull was inspired by gin-gonic, my favorite web framework for Golang. Lightweight, easy to use, minimum features set but really fast.\n\n## News\nProject updated to the version 0.2.5. The main feature is new, much more faster Router. \nhttps://github.com/gavrilaf/SgRouter\n\n## Getting Started\n\nBuild \u0026 start test REST server.\n```\nswift run SeagullRestDemo\n```\nor using make\n```\nmake run-rest \n```\n\nRun integration tests for base rest server implementation\n```\nmake ptest\n```\n\n## Run using docker-compose\n\nRun unit tests \n\n```\ndocker-compose -f docker/docker-compose.yaml up unit-tests\n```\n\nRun Rest server example\n\n```\ndocker-compose -f docker/docker-compose.yaml up rest\n```\n\n## API Examples\n\n```swift\nvar router = HttpRouter()\ntry router.GET(\"/\", handler: Handlers.ping)\ntry router.GET(\"whoami\", handler: Handlers.whoami, with: [Handlers.tokenMiddleware])\n    \nlet engine = Engine(router: router)\ntry engine.run(host: host, port: port)\n    \ndefer { try! engine.close() }\ntry engine.waitForCompletion()\n```\n\n### Parameters in path\n\n```swift\ntry router.GET(\"/profile/shared/:username\", handler: Handlers.getProfile)\n\nstatic func getProfile(_ request: SgRequest, _ ctx: SgRequestContext) -\u003e SgResult {\n  do {\n    guard let username = request.urlParams[\"username\"] else { throw AppLogicError.invalidParam }\n    let profile = try Db.inst.getProfile(username: username)\n    .....\n  } catch let err {\n    return ctx.error(err)\n  }\n}\n```\n\n### Querystring parameters\n\n```swift\ntry router.GET(\"/withParams\", handler: { (req, ctx) -\u003e SgResult in\n  let p1 = req.queryParams[\"paramOne\"] ?? \"not-found\"\n  let p2 = req.queryParams[\"paramTwo\"] ?? \"not-found\"\n  .....\n}\n\n.../withParams?paramOne=abc\u0026paramTwo=100\n\n```\n\n### Grouping routes\n\n```swift\ntry router.group(\"/auth\") {\n    try $0.PUT(\"/register\", handler: Handlers.register)\n    try $0.POST(\"/login\", handler: Handlers.login)\n}\n```\n\n### Using middleware\n\n```swift\ntry router.group(\"/profile\", middleware: [Handlers.tokenMiddleware, logMiddleware, ...]) {\n  try $0.GET(\"/\", handler: Handlers.getMyProfile)\n  try $0.POST(\"/\", handler: Handlers.updateProfile)\n  try $0.DELETE(\"/\", handler: Handlers.deleteProfile)\n}\n```\n\nMiddleware handlers will be called before the main handler in the order they are passed.\n\n### Catch-all parameters\n\n```swift\nlet siteContentHandler: RequestHandler = { (req, ctx) in\n    let pathParam = req.urlParams[\"path\"]!\n    let path = FileManager.default.currentDirectoryPath + \"/html/\" + pathParam\n    return SgResult.file(response: SgFileResponse(path: path, headers: mimeType))\n}\n........\ntry router.GET(\"/site/*path\", handler: siteContentHandler)\n........\n\n.../site/index.html\n.../site/images/logo.jpg\n\n```\n\n**Project is in active development and isn't ready for production usage yet. But it's good for experiments :)**\n\nCurrent version is 0.2.5\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgavrilaf%2Fseagull","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgavrilaf%2Fseagull","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgavrilaf%2Fseagull/lists"}