如何在net / http中编写/ api / v1 / users / id / {id}?

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