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]) }