Skip to content

Commit

Permalink
Combine endpoint and group
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-fowler committed Jan 30, 2021
1 parent 3676c23 commit 946e98c
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 132 deletions.
7 changes: 4 additions & 3 deletions Sources/Hummingbird/Router/Router.swift
Expand Up @@ -63,12 +63,13 @@ extension HBRouter {
}

/// return new `RouterGroup`
public func group() -> HBRouterGroup {
return .init(router: self)
/// - Parameter path: prefix to add to paths inside the group
public func group(_ path: String = "") -> HBRouterGroup {
return .init(path: path, router: self)
}

/// return new `RouterEndpoint`
public func endpoint(_ path: String) -> HBRouterEndpoint {
public func endpoint(_ path: String) -> HBRouterGroup {
return .init(path: path, router: self)
}
}
113 changes: 0 additions & 113 deletions Sources/Hummingbird/Router/RouterEndpoint.swift

This file was deleted.

57 changes: 45 additions & 12 deletions Sources/Hummingbird/Router/RouterGroup.swift
Expand Up @@ -2,35 +2,41 @@ import HummingbirdCore
import NIO
import NIOHTTP1

/// Used to group together routes with additional middleware applied
/// Used to group together routes under a single path. Additional middleware can be added to the endpoint and each route can add a
/// suffix to the endpoint path
///
/// The below create an `HBRouteEndpoint`with path "todos" and adds GET and PUT routes on "todos" and adds GET, PUT and
/// DELETE routes on "todos/:id" where id is the identifier for the todo
/// ```
/// let group = app.router
/// .group()
/// .add(middleware: MyMiddleware())
/// group
/// .get("path", use: myController.get)
/// .put("path", use: myController.put)
/// app.router
/// .endpoint("todos")
/// .get(use: todoController.list)
/// .put(use: todoController.create)
/// .get(":id", use: todoController.get)
/// .put(":id", use: todoController.update)
/// .delete(":id", use: todoController.delete)
/// ```
public struct HBRouterGroup: HBRouterMethods {
let path: String
let router: HBRouter
let middlewares: HBMiddlewareGroup

init(router: HBRouter) {
init(path: String = "", middlewares: HBMiddlewareGroup = .init(), router: HBRouter) {
self.path = path
self.router = router
self.middlewares = .init()
self.middlewares = middlewares
}

/// Add middleware to RouterEndpoint
public func add(middleware: HBMiddleware) -> HBRouterGroup {
self.middlewares.add(middleware)
return self
}

public func endpoint(_ path: String) -> HBRouterEndpoint {
return HBRouterEndpoint(path: path, middlewares: self.middlewares, router: self.router)

/// Return a group inside the current group
/// - Parameter path: path prefix to add to routes inside this group
public func group(_ path: String = "") -> HBRouterGroup {
return HBRouterGroup(path: self.combinePaths(self.path, path), middlewares: self.middlewares, router: self.router)
}

/// Add path for closure returning type conforming to ResponseFutureEncodable
Expand All @@ -45,6 +51,7 @@ public struct HBRouterGroup: HBRouterMethods {
return try closure(request).response(from: request).apply(patch: request.optionalResponse)
}
}
let path = self.combinePaths(self.path, path)
self.router.add(path, method: method, responder: self.middlewares.constructResponder(finalResponder: responder))
return self
}
Expand All @@ -63,6 +70,7 @@ public struct HBRouterGroup: HBRouterMethods {
.hop(to: request.eventLoop)
}
}
let path = self.combinePaths(self.path, path)
self.router.add(path, method: method, responder: self.middlewares.constructResponder(finalResponder: responder))
return self
}
Expand All @@ -80,7 +88,32 @@ public struct HBRouterGroup: HBRouterMethods {
.map { $0.apply(patch: request.optionalResponse) }
.hop(to: request.eventLoop)
}
let path = self.combinePaths(self.path, path)
self.router.add(path, method: method, responder: self.middlewares.constructResponder(finalResponder: responder))
return self
}

private func combinePaths(_ path1: String, _ path2: String) -> String {
let path1 = path1.dropSuffix("/")
let path2 = path2.dropPrefix("/")
return "\(path1)/\(path2)"
}
}

private extension String {
func dropPrefix(_ prefix: String) -> Substring {
if hasPrefix(prefix) {
return self.dropFirst(prefix.count)
} else {
return self[...]
}
}

func dropSuffix(_ suffix: String) -> Substring {
if hasSuffix(suffix) {
return self.dropLast(suffix.count)
} else {
return self[...]
}
}
}
8 changes: 4 additions & 4 deletions Tests/HummingbirdTests/RouterTests.swift
Expand Up @@ -75,19 +75,19 @@ final class RouterTests: XCTestCase {
}
}

func testGroupEndpointMiddleware() {
func testGroupGroupMiddleware() {
let app = HBApplication(testing: .embedded)
app.router
.group()
.group("/test")
.add(middleware: TestMiddleware())
.endpoint("/group")
.group("/group")
.get { _ in
return "hello"
}
app.XCTStart()
defer { app.XCTStop() }

app.XCTExecute(uri: "/group", method: .GET) { response in
app.XCTExecute(uri: "/test/group", method: .GET) { response in
XCTAssertEqual(response.headers["middleware"].first, "TestMiddleware")
}
}
Expand Down

0 comments on commit 946e98c

Please sign in to comment.