英文:
Gorilla Mux - not routing as expected
问题
帮助将不胜感激,显然我错过了一些非常简单的东西。
我创建了一个应该很简单的测试装置,将调用路由到不同的处理程序的不同方法。
但是,简单的获取处理程序获取了所有的获取请求,而删除和放置请求则无法识别!
所以,localhost:8080/users 和 localhost:8080/users?id=1 都被路由到了getUsers路由。这个问题的答案肯定很简单,但我看不到,所以希望你能帮助我。
以下是测试装置的完整列表:
package main
import (
"encoding/json"
"fmt"
"github.com/gorilla/mux"
"log"
"net/http"
)
type User struct {
Id string `json:"id"`
Name string `json:"name"`
}
type Users []User
var users = Users{
User{
Id: "1",
Name: "Tula",
},
User{
Id: "2",
Name: "Monty",
},
User{
"3",
"Merry",
},
User{
Id: "4",
Name: "Paddy",
},
User{
Id: "5",
Name: "Hendrix",
},
User{
Id: "6",
Name: "Purdy",
},
User{
Id: "7",
Name: "turnip",
},
}
func main() {
r := mux.NewRouter()
r.Path("/users/{id:[0-9]+}").
Queries("id", "{id:[0-9]*?}").
Methods(http.MethodGet).
HandlerFunc(getUser).
Name("getUser")
r.Path("/users").
Methods(http.MethodGet).
HandlerFunc(getUsers).
Name("getUsers")
r.Path("/users").
Methods(http.MethodPost).
HandlerFunc(CreateUser).
Name("CreateUser")
r.Path("/users/{id:[0-9]+}").
Queries("id", "{id:[0-9]*?}").
Methods(http.MethodPut).
HandlerFunc(updateUser).
Name("updateUser")
r.Path("/users/{id:[0-9]+}").
Queries("id", "{id:[0-9]*?}").
Methods(http.MethodDelete).
HandlerFunc(deleteUser).
Name("deleteUser")
log.Fatal(http.ListenAndServe(":8080", r))
}
func getUsers(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
err := json.NewEncoder(w).Encode(users)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
} else {
_, _ = fmt.Fprintf(w, "GetUsers!")
}
}
func getUser(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
_, _ = fmt.Fprintf(w, "GetUser!")
}
func CreateUser(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
_, _ = fmt.Fprintf(w, "CreateUser!")
var newUser User
err := json.NewDecoder(r.Body).Decode(&newUser)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
} else {
users = append(users, newUser)
_ = json.NewEncoder(w).Encode(users)
}
}
func updateUser(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
_, _ = fmt.Fprintf(w, "Update!")
}
func deleteUser(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
_, _ = fmt.Fprintf(w, "Delete!")
}
希望这可以帮助你找到问题所在。
英文:
Help would be appreciated, clearly i am missing something very simple.
I have created what should be a simple test rig to route calls to different methods to different handlers.
In stead the simple get handler is getting all get requests and delete and put are not recognised!
so both localhost:8080/users
and
localhost:8080/users?id=1
get. routed to the getUsers route. The answer to this must be trivial but i cant see it and hence you help would be appreciated.
Below is a complete listing of the test rig
package main
import (
"encoding/json"
"fmt"
"github.com/gorilla/mux"
"log"
"net/http"
)
type User struct {
Id string `json:"id"`
Name string `json:"name"`
}
type Users []User
var users = Users{
User{
Id: "1",
Name: "Tula",
},
User{
Id: "2",
Name: "Monty",
},
User{
"3",
"Merry",
},
User{
Id: "4",
Name: "Paddy",
},
User{
Id: "5",
Name: "Hendrix",
},
User{
Id: "6",
Name: "Purdy",
},
User{
Id: "7",
Name: "turnip",
},
}
func main() {
r := mux.NewRouter()
r.Path("/users/{id:[0-9]+}").
Queries("id", "{id:[0-9]*?}").
Methods(http.MethodGet).
HandlerFunc(getUser).
Name("getUser")
r.Path("/users").
Methods(http.MethodGet).
HandlerFunc(getUsers).
Name("getUsers")
r.Path("/users").
Methods(http.MethodPost).
HandlerFunc(CreateUser).
Name("CreateUser")
r.Path("/users/{id:[0-9]+}").
Queries("id", "{id:[0-9]*?}").
Methods(http.MethodPut).
HandlerFunc(updateUser).
Name("updateUser")
r.Path("/users/{id:[0-9]+}").
Queries("id", "{id:[0-9]*?}").
Methods(http.MethodDelete).
HandlerFunc(deleteUser).
Name("deleteUser")
log.Fatal(http.ListenAndServe(":8080", r))
}
func getUsers(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
err := json.NewEncoder(w).Encode(users)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
} else {
_, _ = fmt.Fprintf(w, "GetUsers!")
}
}
func getUser(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
_, _ = fmt.Fprintf(w, "GetUser!")
}
func CreateUser(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
_, _ = fmt.Fprintf(w, "CreateUser!")
var newUser User
err := json.NewDecoder(r.Body).Decode(&newUser)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
} else {
users = append(users, newUser)
_ = json.NewEncoder(w).Encode(users)
}
}
func updateUser(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
_, _ = fmt.Fprintf(w, "Update!")
}
func deleteUser(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
_, _ = fmt.Fprintf(w, "Delete!")
}
答案1
得分: 2
当你获取url localhost:8080/users?id=1
时,路径是/users
。唯一映射到GET /users
的路径是:
r.Path("/users").
Methods(http.MethodGet).
HandlerFunc(getUsers).
Name("getUsers")
这就是为什么请求映射到getUsers
方法。getUser
的配置实际上没有任何意义。你有:
r.Path("/users/{id:[0-9]+}").
Queries("id", "{id:[0-9]*?}").
Methods(http.MethodGet).
HandlerFunc(getUser).
Name("getUser")
这将需要一个类似于http://localhost:8080/users/1?id=1
的请求(然后忽略路径中的id)。我会修改配置,使其如下所示:
r.Path("/users/{id:[0-9]+}").
Methods(http.MethodGet).
HandlerFunc(getUser).
Name("getUser")
然后你的请求将变成http://localhost:8080/users/1
,http://localhost:8080/users/2
等等。
英文:
When you fetch the url localhost:8080/users?id=1
, the path is /users
. The only path that maps to GET /users
is:
r.Path("/users").
Methods(http.MethodGet).
HandlerFunc(getUsers).
Name("getUsers")
That's why the request maps to the getUsers
method. The configuration for getUser
doesn't actually make any sense. You have:
r.Path("/users/{id:[0-9]+}").
Queries("id", "{id:[0-9]*?}").
Methods(http.MethodGet).
HandlerFunc(getUser).
Name("getUser")
Which would require a request like to something like http://localhost:8080/users/1?id=1
(and then it ignores the id in the path). I would modify the configuration to look like this:
r.Path("/users/{id:[0-9]+}").
Methods(http.MethodGet).
HandlerFunc(getUser).
Name("getUser")
And then your requests would look like http://localhost:8080/users/1
, http://localhost:8080/users/2
, etc.
答案2
得分: 0
简单来说,只需要将代码中的路径部分从/users/{id:[0-9]+}
改为/users
,同时将处理函数getUser
改为GetUser
即可。
英文:
Simple in the end only
r.Path("/users/{id:[0-9]+}").
Queries("id", "{id:[0-9]*?}").
Methods(http.MethodGet).
HandlerFunc(getUser).
Name("updateUser")
Became
r.Path("/users").
Queries("id", "{id:[0-9]*?}").
Methods(http.MethodGet).
HandlerFunc(GetUser).
Name("updateUser")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论