72 lines
1.3 KiB
Go
72 lines
1.3 KiB
Go
|
package glue
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"net/http"
|
||
|
"sort"
|
||
|
"sync"
|
||
|
|
||
|
"github.com/gorilla/mux"
|
||
|
)
|
||
|
|
||
|
// Endpoint is a handler attached to a path.
|
||
|
type Endpoint struct {
|
||
|
Path string
|
||
|
Methods []string
|
||
|
Middleware []mux.MiddlewareFunc
|
||
|
Handler func(w http.ResponseWriter, r *http.Request)
|
||
|
}
|
||
|
|
||
|
var (
|
||
|
registry = map[string]Endpoint{}
|
||
|
registryLock sync.RWMutex
|
||
|
)
|
||
|
|
||
|
//////////////////////////
|
||
|
|
||
|
// Register a controller.
|
||
|
func Register(e Endpoint) {
|
||
|
registryLock.Lock()
|
||
|
if _, ok := registry[e.Path]; ok {
|
||
|
panic(fmt.Sprintf("Route Registry: path '%s' already registered", e.Path))
|
||
|
}
|
||
|
registry[e.Path] = e
|
||
|
registryLock.Unlock()
|
||
|
}
|
||
|
|
||
|
// GetControllers returns all the routes and handler functions.
|
||
|
func GetControllers() []Endpoint {
|
||
|
registryLock.RLock()
|
||
|
defer registryLock.RUnlock()
|
||
|
|
||
|
// Sort the endpoints by longest first.
|
||
|
var keys = make([]string, len(registry))
|
||
|
var i int
|
||
|
for key := range registry {
|
||
|
keys[i] = key
|
||
|
i++
|
||
|
}
|
||
|
|
||
|
sort.Sort(byLength(keys))
|
||
|
|
||
|
result := make([]Endpoint, len(registry))
|
||
|
for i, key := range keys {
|
||
|
result[i] = registry[key]
|
||
|
}
|
||
|
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
type byLength []string
|
||
|
|
||
|
func (s byLength) Len() int {
|
||
|
return len(s)
|
||
|
}
|
||
|
func (s byLength) Swap(i, j int) {
|
||
|
s[i], s[j] = s[j], s[i]
|
||
|
}
|
||
|
func (s byLength) Less(i, j int) bool {
|
||
|
// Sort longest over shortest.
|
||
|
return len(s[j]) < len(s[i])
|
||
|
}
|