which can be updated on the fly by applications as they deploy. They can register themselves: { "id": "whitehall", "url": "http://whitehall.internal" } And their routes: { "type": "exact", "path": "/airport-rights", "application_id": "frontend" } { "type": "prefix", "path": "/government", "application_id": "whitehall" }
url.Parse("http://google.com") aaplUrl, _ := url.Parse("http://apple.com") goog := httputil.NewSingleHostReverseProxy(googUrl) aapl := httputil.NewSingleHostReverseProxy(aaplUrl) // register a prefix route pointing to the Google backend (all requests to // "/google<anything>" will go to this backend) mux.Handle("/google", true, goog) // register an exact (non-prefix) route pointing to the Apple backend mux.Handle("/apple", false, aapl) log.Println("Listening on :8088") log.Fatalln(http.ListenAndServe(":8088", mux)) Run
reference to the previous mux in case we have to restore it oldmux := rt.mux defer func() { if r := recover(); r != nil { log.Println("router: recovered from panic in ReloadRoutes:", r) rt.mux = oldmux log.Println("router: original routes have been restored") } }() ... sess, err := mgo.Dial(rt.mongoUrl) ... newmux := triemux.NewMux() apps := loadApplications(db.C("applications"), newmux) loadRoutes(db.C("routes"), newmux, apps) ... rt.mux = newmux log.Printf("router: reloaded routes") }
work, with no attempt at optimization. Contributing factors in Go's effectiveness: Dealing with error conditions up front The defer, recover() pattern Interfaces (is a bare pointer really the right answer?) Composition of simple components (Trie, TrieMux, Router) Rich standard library