Parece que ya ha aceptado una respuesta, pero quería proponer una solución alternativa.
Cuestiono la necesidad de agregar un muxer personalizado. En este ejemplo estoy usando el gorila muxer, sin embargo, eso es solo porque estoy familiarizado con su coincidencia de patrones. En teoría, podría hacer coincidir el patrón de la URL entrante sin la necesidad de reemplazar el muxer predeterminado.
Mi código mantiene las funciones del controlador en un mapa (cadena: el nombre del manejador => literal de la función) ... Esto es adecuado para usar el método muletero HandleFunc predeterminado.
entrada de la muestra/salida:
obtener/registrar/123
GET/123
hello from123.
GET/destruir/123
GET/123
[nothing]
package main
import (
"code.google.com/p/gorilla/mux"
"flag"
"log"
"net/http"
)
// Wraps server muxer, dynamic map of handlers, and listen port.
type Server struct {
Dispatcher *mux.Router
Urls map[string]func(w http.ResponseWriter, r *http.Request)
Port string
}
// May the signal never stop.
func main() {
//Initialize Server
server := &Server{Port: "3000", Dispatcher: mux.NewRouter(), Urls: make(map[string]func(w http.ResponseWriter, r *http.Request))}
var port = flag.String("port", "3000", "Default: 3000; Set the port for the web-server to accept incoming requests")
flag.Parse()
server.Port = *port
log.Printf("Starting server on port: %s \n", server.Port)
server.InitDispatch()
log.Printf("Initializing request routes...\n")
server.Start() //Launch server; blocks goroutine.
}
func (s *Server) Start() {
http.ListenAndServe(":"+s.Port, s.Dispatcher)
}
// Initialize Dispatcher's routes.
func (s *Server) InitDispatch() {
d := s.Dispatcher
// Add handler to server's map.
d.HandleFunc("/register/{name}", func(w http.ResponseWriter, r *http.Request) {
//somewhere somehow you create the handler to be used; i'll just make an echohandler
vars := mux.Vars(r)
name := vars["name"]
s.AddFunction(w, r, name)
}).Methods("GET")
d.HandleFunc("/destroy/{name}", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
name := vars["name"]
s.Destroy(name)
}).Methods("GET")
d.HandleFunc("/{name}", func(w http.ResponseWriter, r *http.Request) {
//Lookup handler in map and call it, proxying this writer and request
vars := mux.Vars(r)
name := vars["name"]
s.ProxyCall(w, r, name)
}).Methods("GET")
}
func (s *Server) Destroy(fName string) {
s.Urls[fName] = nil //remove handler
}
func (s *Server) ProxyCall(w http.ResponseWriter, r *http.Request, fName string) {
if s.Urls[fName] != nil {
s.Urls[fName](w, r) //proxy the call
}
}
func (s *Server) AddFunction(w http.ResponseWriter, r *http.Request, fName string) {
f := func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello from" + fName))
}
s.Urls[fName] = f // Add the handler to our map
}
La preocupación es que el registro de controladores seguirá creciendo con el tiempo y causará una desaceleración en el cambio de solicitudes debido a las búsquedas de controladores cada vez más costosas. –