php editor Banana is here to answer a common question for everyone: using POST to add to GET the same endpoint and different queries, you may end up with inconsistent error messages. In web development, GET and POST are commonly used HTTP request methods for delivering data to the server. The GET method appends the data to the URL, while the POST method encapsulates the data in the request body. When we add a POST request to the same endpoint of a GET request, inconsistent error messages may occur if the query parameters are different. This is because the server processes the request based on the request method and query parameters. Different query parameters may cause the server to return different results. Therefore, when using POST and GET requests, we need to pay attention to the consistency of endpoints and query parameters to avoid unexpected error messages.
When adding the same route using different methods, the response of each method query get call is different, but since the other method is post, it should not be affected Influence.
Via Post: Playground: https://go.dev/play/p/xzoakpehggy
// you can edit this code! // click here and start typing. package main import ( "encoding/json" "fmt" "net/http" "net/http/httptest" "time" "github.com/gorilla/mux" ) func main() { r := mux.newrouter() r.handlefunc("/api/v2", func(w http.responsewriter, r *http.request) { // an example api handler fmt.fprintf(w, "you made a post request") json.newencoder(w).encode(map[string]bool{"ok": true}) }).methods("post") r.handlefunc("/api/v2", func(w http.responsewriter, r *http.request) { // an example api handler fmt.fprintf(w, "you made a get request") json.newencoder(w).encode(map[string]bool{"ok": true}) }). queries("from", "{from:[0-9]+}", "to", "{to:[0-9]+}").methods("get") srv := &http.server{ handler: r, addr: "127.0.0.1:8000", // good practice: enforce timeouts for servers you create! writetimeout: 15 * time.second, readtimeout: 15 * time.second, } go srv.listenandserve() req2 := httptest.newrequest("get", "/api/v2?from=3&to=-5", nil) out2 := httptest.newrecorder() r.servehttp(out2, req2) fmt.println(out2.code) fmt.println(out2) }
Expected to be 404, actual 405
When deleting a post Playground: https://go.dev/play/p/exif00_wrfw
// You can edit this code! // Click here and start typing. package main import ( "encoding/json" "fmt" "net/http" "net/http/httptest" "time" "github.com/gorilla/mux" ) func main() { r := mux.NewRouter() r.HandleFunc("/api/v2", func(w http.ResponseWriter, r *http.Request) { // an example API handler fmt.Fprintf(w, "You made a GET request") json.NewEncoder(w).Encode(map[string]bool{"ok": true}) }). Queries("from", "{from:[0-9]+}", "to", "{to:[0-9]+}").Methods("GET") srv := &http.Server{ Handler: r, Addr: "127.0.0.1:8000", // Good practice: enforce timeouts for servers you create! WriteTimeout: 15 * time.Second, ReadTimeout: 15 * time.Second, } go srv.ListenAndServe() req2 := httptest.NewRequest("GET", "/api/v2?from=3&to=-5", nil) out2 := httptest.NewRecorder() r.ServeHTTP(out2, req2) fmt.Println(out2.Code) }
The result is 404
For get requests, routing and results should be consistent. 404-s
I'm curious if anyone has encountered this problem before?
The router will try to find a match based on the path and query parameters. The get route was not matched because the query string parameters did not meet the requirements.
But this path matches the post route because that route doesn't care about these query parameters. Then checking the request method, it doesn't match the route, so 405 method not allowed
is returned (the route has a handler, but the method is different).
You can get the desired behavior by adding a catch-all get handler for the same path:
// You can edit this code! // Click here and start typing. package main import ( "encoding/json" "fmt" "net/http" "net/http/httptest" "time" "github.com/gorilla/mux" ) func main() { r := mux.NewRouter() r.HandleFunc("/api/v2", func(w http.ResponseWriter, r *http.Request) { // an example API handler fmt.Fprintf(w, "You made a POST request") json.NewEncoder(w).Encode(map[string]bool{"ok": true}) }).Methods("POST") r.HandleFunc("/api/v2", func(w http.ResponseWriter, r *http.Request) { // an example API handler fmt.Fprintf(w, "You made a GET request") json.NewEncoder(w).Encode(map[string]bool{"ok": true}) }). Queries("from", "{from:[0-9]+}", "to", "{to:[0-9]+}"). Methods("GET") r.HandleFunc("/api/v2", func(w http.ResponseWriter, r *http.Request) { http.Error(w, "", http.StatusNotFound) }).Methods("GET") srv := &http.Server{ Handler: r, Addr: "127.0.0.1:8000", // Good practice: enforce timeouts for servers you create! WriteTimeout: 15 * time.Second, ReadTimeout: 15 * time.Second, } go srv.ListenAndServe() req2 := httptest.NewRequest("GET", "/api/v2?from=3&to=-5", nil) out2 := httptest.NewRecorder() r.ServeHTTP(out2, req2) fmt.Println(out2.Code) }
The above is the detailed content of Using POST to add to GET same endpoint and different queries end up with inconsistent error messages. For more information, please follow other related articles on the PHP Chinese website!