For example, I want to do /api/v1/users/id/{id}
.
At the moment, I have this:
mux := http.NewServeMux()
mux.Handle("/api/v1/users", HandleUsersV1{db: db, mux: mux})
log.Fatal(http.ListenAndServe(fmt.Sprintf("%s%d", ":", portNumber), mux))
I want:
mux := http.NewServeMux()
mux.Handle("/api/v1", HandleV1{})
And then in HandleV1
:
mux.HandleFunc("/users/{id}", handler)
I know Gorilla Mux can do it for me with PathPrefix
, but I prefer net/http
.
The standard net/http
does not support dynamic path segments, so /{id}
is not gonna work the way you might imagine. As for the prefix thing, you can use this https://golang.org/pkg/net/http/#StripPrefix.
v1mux := http.NewServeMux()
v1mux.HandleFunc("/users/", handler)
mux := http.NewServeMux()
mux.Handle("/api/v1/", http.StripPrefix("/api/v1", v1mux))
log.Fatal(http.ListenAndServe(fmt.Sprintf("%s%d", ":", portNumber), mux))
I suggest using https://github.com/julienschmidt/httprouter. But if you insist.
package main
import (
"log"
"net/http"
"strconv"
"strings"
)
func main() {
res := resourceone{}
http.HandleFunc("/api/v1/users/", res.router)
log.Fatal(http.ListenAndServe(":8080", nil))
}
type resourceone struct {
}
func (res *resourceone) router(w http.ResponseWriter, r *http.Request) {
args := strings.Split(r.URL.String()[len(`/api/v1/users/`):], `/`)
switch args[0] {
case `id`:
id, _ := strconv.Atoi(args[1])
res.one(w, r, id)
case `name`:
res.two(w, r, args[1])
}
}
func (res *resourceone) one(w http.ResponseWriter, r *http.Request, id int) {
w.Write([]byte(strconv.Itoa(id)))
}
func (res *resourceone) two(w http.ResponseWriter, r *http.Request, name string) {
w.Write([]byte(name))
}
Test:
curl 127.0.0.1:8080/api/v1/users/name/david
curl 127.0.0.1:8080/api/v1/users/id/1234