Web support for the Website service (#17)
This PR contains the work done to introduce a new Web Swift package that provides a reusable, declarative way to register route controllers on a Hummingbird router, then adopt it in the Website service.
To provide further details about the work:
* Web package
* The `RouterController` protocol — a Sendable protocol to group controllers behind one `routes` property.
* The `RouteCollectionBuilder` — a result builder that collects controllers' route collections into a stack, with full support for optionals, conditionals, and arrays.
* The `addController(_:)` method — a `RouterMethods` extension letting controllers be listed declaratively and adding each one's routes at the router root.
* Website service
* Added Web as a dependency of the _WebsiteLibrary_ target.
* Conformed the `RootController` and `HealthController`controllers to the `RouterController` protocol.
* Updated the `App+Build` extension to to use the cleaner `router.addController { … }` instead.
Reviewed-on: rock-n-code/loud-amsterdam#17
Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
This commit is contained in:
@@ -1,17 +1,20 @@
|
||||
import Hummingbird
|
||||
import Web
|
||||
|
||||
/// Serves the website's root routes.
|
||||
///
|
||||
/// The controller exposes its routes as a `RouteCollection` so they can be added to a router
|
||||
/// (or a sub-group) by the application that composes it:
|
||||
/// The controller exposes its routes through its `RouterController` conformance, so the
|
||||
/// application that composes it registers them declaratively:
|
||||
///
|
||||
/// ```swift
|
||||
/// router.addRoutes(RootController<AppRequestContext>().routes)
|
||||
/// router.addController {
|
||||
/// RootController<AppRequestContext>()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// - Note: `Context` is the request context the routes are resolved against, and must match the
|
||||
/// context of the router the routes are added to.
|
||||
public struct RootController<Context: LocalizedRequestContext>: Sendable {
|
||||
public struct RootController<Context: LocalizedRequestContext> {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
@@ -25,12 +28,14 @@ public struct RootController<Context: LocalizedRequestContext>: Sendable {
|
||||
self.responses = .init { IndexPage(locale: $0) }
|
||||
}
|
||||
|
||||
// MARK: Computed
|
||||
}
|
||||
|
||||
// MARK: - RouteController
|
||||
|
||||
extension RootController: RouterController {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// The routes served by the controller.
|
||||
///
|
||||
/// Serves a `GET` request for the root path (`/`) by rendering the ``IndexPage`` in the
|
||||
/// language negotiated for the request.
|
||||
public var routes: RouteCollection<Context> {
|
||||
let routes = RouteCollection(context: Context.self)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user