handler.go
36 lines1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package router
import "net/http"
// Handler is the unit of composition in Congo: a function that wraps the next
// http.Handler and returns a replacement. Every middleware — a logger, an IP
// filter, a security guard, the application itself — is a Handler.
//
// Packages in other layers produce Handlers structurally: application.New and
// security.New already return func(http.Handler) http.Handler, which is
// assignable to Handler, so they plug into a Router without importing router.
// The type names the shape without forcing a dependency edge.
type Handler func(http.Handler) http.Handler
// Router is a statically-declared chain of Handlers. The first is outermost
// (closest to the wire); the last is terminal (typically the application). It
// is just a slice, so applications declare their stack as data:
//
// var App = router.Router{
// router.WithLogger(),
// router.IpBlockList("203.0.113.0/24"),
// security.New(security.WithNonce(), security.WithHeaders()),
// application.New(views, application.WithController(controllers.Home())),
// }
// func main() { App.Listen() }
type Router []Handler
// build folds the chain into a single http.Handler and wraps it in domain-based
// proxy routing. The terminal floor is 404. The first Handler ends up outermost.
func (r Router) build() http.Handler {
var h http.Handler = http.NotFoundHandler()
for i := len(r) - 1; i >= 0; i-- {
h = r[i](h)
}
return demux(h)
}