Я создаю API и хотел бы разделить конечные точки по функциям, поскольку увидел, что пакет net/http получил обновление, поэтому хотел попробовать его использовать.
Конечная точка /v1/user доставляет мне проблемы и не возвращает ожидаемые данные. Вот некоторые curl, которые могут помочь:
$ curl -X 'GET' 'http://localhost:5000/v1/user/john'
GET /v1/user/{username}
$ curl -X 'GET' 'http://localhost:5000/v1/user/'
GET /v1/user
$ curl -X 'GET' 'http://localhost:5000/v1/user'
<a href = "/user/">Moved Permanently</a>.
Вот мой текущий код (я удалил лишние конечные точки):
// will be moved of the user.go file
userRouter := http.NewServeMux()
userRouter.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("GET /v1/user"))
})
userRouter.HandleFunc("GET /{username}", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("GET /v1/user/{username}"))
})
// will remain inside api.go
v1 := http.NewServeMux()
v1.Handle("/user/", http.StripPrefix("/user", userRouter))
main := http.NewServeMux()
main.Handle("/v1/", http.StripPrefix("/v1", v1))
server := &http.Server{ Addr: "localhost:5000", Handler: main }
server.ListenAndServe()
Я попытался изменить путь конечной точки с "GET /" на "GET" или на "", но, очевидно, синтаксис неправильный.
Я попытался изменить путь обработчика userRouter с "/user/" на "/user", это приведет к тому, что все конечные точки перестанут работать.
$ curl -X 'GET' 'http://localhost:5000/v1/user/john'
404 page not found
$ curl -X 'GET' 'http://localhost:5000/v1/user/'
404 page not found
$ curl -X 'GET' 'http://localhost:5000/v1/user'
<a href = "/">Moved Permanently</a>.
http.StripPrefix к маршрутизатору userRounter и добавлением /user к конечным точкам; единственная работающая конечная точка — это /v1/user. Код:userRouter := http.NewServeMux()
userRouter.HandleFunc("GET /user", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("GET /v1/user"))
})
userRouter.HandleFunc("GET /user/{username}", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("GET /v1/user/{username}"))
})
v1 := http.NewServeMux()
v1.Handle("/user", userRouter)
main := http.NewServeMux()
main.Handle("/v1/", http.StripPrefix("/v1", v1))
server := &http.Server{ Addr: "localhost:5000", Handler: main }
server.ListenAndServe()
Запросы:
$ curl -X 'GET' 'http://localhost:5000/v1/user/john'
404 page not found
$ curl -X 'GET' 'http://localhost:5000/v1/user/'
404 page not found
$ curl -X 'GET' 'http://localhost:5000/v1/user'
GET /v1/user
Также рассмотрите возможность использования io.WriteString(w, "foo") вместо w.Write([]byte("foo")).

проблема вот в чем v1.Handle("/user", userRouter) ты забыл добавить /
package main
import (
"net/http"
)
func main() {
userRouter := http.NewServeMux()
userRouter.HandleFunc("GET /user", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("GET /v1/user"))
})
userRouter.HandleFunc("GET /user/{username}", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("GET /v1/user/{username}"))
})
v1 := http.NewServeMux()
v1.Handle("/user/", userRouter)
v1.Handle("/user", userRouter)
main := http.NewServeMux()
main.Handle("/v1/", http.StripPrefix("/v1", v1))
server := &http.Server{Addr: "localhost:5000", Handler: main}
server.ListenAndServe()
}
Я бы порекомендовал вам написать простой код маршрутизации, подобный этому
package main
import (
"net/http"
)
func main() {
v1 := http.NewServeMux()
v1.HandleFunc("/v1/user", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("GET /v1/user"))
})
v1.HandleFunc("GET /v1/user/{username}", func(w http.ResponseWriter, r *http.Request) {
username := r.PathValue("username")
w.Write([]byte("GET /v1/user/" + username))
})
server := &http.Server{Addr: "localhost:5000", Handler: v1}
server.ListenAndServe()
}
Обрабатывайте /user и /user/, как описано в pkg.go.dev/net/http#hdr-Trailing_slash_redirection