Skip to content

Latest commit

 

History

History
124 lines (91 loc) · 2.92 KB

README.md

File metadata and controls

124 lines (91 loc) · 2.92 KB

Seagull

Swift web framework based on the swift-nio.

The 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.

News

Project updated to the version 0.2.5. The main feature is new, much more faster Router. https://github.com/gavrilaf/SgRouter

Getting Started

Build & start test REST server.

swift run SeagullRestDemo

or using make

make run-rest 

Run integration tests for base rest server implementation

make ptest

Run using docker-compose

Run unit tests

docker-compose -f docker/docker-compose.yaml up unit-tests

Run Rest server example

docker-compose -f docker/docker-compose.yaml up rest

API Examples

var router = HttpRouter()
try router.GET("/", handler: Handlers.ping)
try router.GET("whoami", handler: Handlers.whoami, with: [Handlers.tokenMiddleware])
    
let engine = Engine(router: router)
try engine.run(host: host, port: port)
    
defer { try! engine.close() }
try engine.waitForCompletion()

Parameters in path

try router.GET("/profile/shared/:username", handler: Handlers.getProfile)

static func getProfile(_ request: SgRequest, _ ctx: SgRequestContext) -> SgResult {
  do {
    guard let username = request.urlParams["username"] else { throw AppLogicError.invalidParam }
    let profile = try Db.inst.getProfile(username: username)
    .....
  } catch let err {
    return ctx.error(err)
  }
}

Querystring parameters

try router.GET("/withParams", handler: { (req, ctx) -> SgResult in
  let p1 = req.queryParams["paramOne"] ?? "not-found"
  let p2 = req.queryParams["paramTwo"] ?? "not-found"
  .....
}

.../withParams?paramOne=abc&paramTwo=100

Grouping routes

try router.group("/auth") {
    try $0.PUT("/register", handler: Handlers.register)
    try $0.POST("/login", handler: Handlers.login)
}

Using middleware

try router.group("/profile", middleware: [Handlers.tokenMiddleware, logMiddleware, ...]) {
  try $0.GET("/", handler: Handlers.getMyProfile)
  try $0.POST("/", handler: Handlers.updateProfile)
  try $0.DELETE("/", handler: Handlers.deleteProfile)
}

Middleware handlers will be called before the main handler in the order they are passed.

Catch-all parameters

let siteContentHandler: RequestHandler = { (req, ctx) in
    let pathParam = req.urlParams["path"]!
    let path = FileManager.default.currentDirectoryPath + "/html/" + pathParam
    return SgResult.file(response: SgFileResponse(path: path, headers: mimeType))
}
........
try router.GET("/site/*path", handler: siteContentHandler)
........

.../site/index.html
.../site/images/logo.jpg

Project is in active development and isn't ready for production usage yet. But it's good for experiments :)

Current version is 0.2.5