I have a map
in Go with routes (e.g. /static/stylesheets/main.css
) as keys and the corresponding code as the value (effectively, a giant string). I was just wondering, is there an easy way in Go by which I can create an HTTP server, which always check an incoming request against the map
and renders the value associated with the matched key, if the key exists?
So far, I have...
func main() {
var m = generateMap()
http.handleFunc("/", renderContent);
}
func renderContent(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, m[path]);
}
I know this code is far from done, but hopefully it clarifies my objective. How would I pass in the path
and m
into renderContent
as well as how do I have handleFunc
actually handle regexes (essentially, any path)?
Make your map an http.Handler
:
type httpFiles struct {
fileMap map[string][]byte
}
func (hf httpFiles) ServeHTTP(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
w.Write(hf.fileMap[path])
}
If you're open to not writing it yourself, something small quick and out of the box - look at gorilla mux. Their toolkit lets you choose the components you want, so just add their mux if all you want is routing with regex.
I found it particularly helpful for obtaining variable from routes.
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
...
vars := mux.Vars(request)
category := vars["category"]
I recommend package httprouter being the fastest go router around. Go's built-in mux is incomplete and slow without an easy way to capture URL parameters.
Also, you might consider making each route a struct so it's easier to handle when you have several routes.
This code captures URL parameter, compare it to the keyword of the map and print the string of code chunk to the console.
package main
import (
"fmt"
"net/http"
"log"
mux "github.com/julienschmidt/httprouter"
)
type Route struct {
Name string
Method string
Pattern string
Handle mux.Handle
}
var codeChunk = map[string]string{ "someUrlPath" : "func printHello(){
\tfmt.Println(\"Hello\")
}" }
var route = Route{
"MyHandler",
"GET",
"/:keywordUrl",
MyHandler,
}
func MyHandler(w http.ResponseWriter, r *http.Request, ps mux.Params) {
// Handle route "/:keywordUrl"
w.WriteHeader(http.StatusOK)
// get the parameter from the URL
path := ps.ByName("keywordUrl")
for key, value := range codeChunk {
// Compare the parameter to the key of the map
if key != "" && path == key {
// do something
fmt.Println(value)
}
}
}
func main() {
router := mux.New()
router.Handle(route.Method, route.Pattern, route.Handle)
log.Fatal(http.ListenAndServe(":8080", router))
// browse to http://localhost:8080/someUrlPath to see
// the map's string value being printed.
}