英文:
What Response Code to return on a non-supported HTTP Method on REST?
问题
我正在使用Gorilla Mux来处理我的REST API的HTTP路由。我正在使用以下绑定来处理我的API:
r := mux.NewRouter()
r.Host(baseUrl)
api := r.PathPrefix("/api").Subrouter()
api.HandleFunc("/users", APIUsers).Methods("GET", "POST")
http.Handle("/", r)
http.ListenAndServe(":8083", nil)
然后我使用CURL进行如下操作:
$ curl -i -X PUT http://127.0.0.1:8083/api/users
预期中,方法APIUsers
没有被调用。但我确实收到了200 OK
的响应:
HTTP/1.1 200 OK
Date: Tue, 30 Dec 2014 19:03:59 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8
我应该如何在Gorilla中进行修改,比如将所有失败的函数绑定到一个指定的函数?另外,我想知道在不支持的函数上返回的典型HTTP状态码是什么。我假设是400
范围内的代码,但我不确定应该使用哪个。我不希望它是200
,因为请求并不是“OK
”。
对此有什么想法和建议吗?
英文:
I'm using Gorilla Mux to handle my HTTP routes for my REST API. I'm using the following binding for my API:
r := mux.NewRouter()
r.Host(baseUrl)
api := r.PathPrefix("/api").Subrouter()
api.HandleFunc("/users", APIUsers).Methods("GET", "POST")
http.Handle("/", r)
http.ListenAndServe(":8083", nil)
Then I do a CURL like this:
$ curl -i -X PUT http://127.0.0.1:8083/api/users
The Method APIUsers
doesn't get called, as expected. I do get a 200 OK
back tho:
HTTP/1.1 200 OK
Date: Tue, 30 Dec 2014 19:03:59 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8
Should I do this different with Gorilla to, let's say, bind all failing functions to a designated function? Also I wonder what's the typical HTTP code to return on non-supported functions. I'm a assuming a code in the 400
range, but I'm not sure which to use. I don't want it to be 200
tho, as the request was not "OK
".
Any ideas and tips on this subject?
答案1
得分: 2
你应该返回的状态码是"405 MethodNotAllowed"或在Go语言中使用http.StatusMethodNowAllowed
。
根据维基百科的解释:
请求使用了资源不支持的请求方法,例如,在需要通过POST提交数据的表单上使用GET方法,或者在只读资源上使用PUT方法。
你可以参考这个链接了解更多关于HTTP状态码的信息:http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
英文:
The status code you should return is "405 MethodNotAllowed" or http.StatusMethodNowAllowed
in go.
From wikipedia:
> A request was made of a resource using a request method not supported
> by that resource; for example, using GET on a form which requires data
> to be presented via POST, or using PUT on a read-only resource.
答案2
得分: 2
你可以设置一个自定义的NotFoundHandler
,但这将适用于所有未匹配的路由。
如果你想返回特定的响应,你需要明确定义路由。
示例:
func main() {
r := mux.NewRouter().PathPrefix("/api").Subrouter()
// 用于未匹配路由的自定义未找到处理程序
var notFound NotFound
r.NotFoundHandler = notFound
r.HandleFunc("/users", APIUsers).Methods("GET", "POST")
// 对于PUT、PATCH和DELETE返回405
r.HandleFunc("/users", status(405, "GET", "POST")).Methods("PUT", "PATCH", "DELETE")
http.Handle("/", r)
http.ListenAndServe(":8083", nil)
}
type NotFound func(w http.ResponseWriter, req *http.Request)
func (NotFound) ServeHTTP(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(404)
w.Write([]byte(`{"message": "Not Found"}`))
}
// status用于设置特定的状态码
func status(code int, allow ...string) func(w http.ResponseWriter, req *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(code)
if len(allow) > 0 {
w.Write([]byte("Allow: " + strings.Join(allow, ", ")))
}
}
}
func APIUsers(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("hello"))
}
英文:
You can set a custom NotFoundHandler
but that will apply to all unmatched routes.
If you want a specific response returned you have to define the route explicitly.
Example:
func main() {
r := mux.NewRouter().PathPrefix("/api").Subrouter()
// custom not found handler used for unmatched routes
var notFound NotFound
r.NotFoundHandler = notFound
r.HandleFunc("/users", APIUsers).Methods("GET", "POST")
// return 405 for PUT, PATCH and DELETE
r.HandleFunc("/users", status(405, "GET", "POST")).Methods("PUT", "PATCH", "DELETE")
http.Handle("/", r)
http.ListenAndServe(":8083", nil)
}
type NotFound func(w http.ResponseWriter, req *http.Request)
func (NotFound) ServeHTTP(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(404)
w.Write([]byte(`{"message": "Not Found"}`))
}
// status is used to set a specific status code
func status(code int, allow ...string) func(w http.ResponseWriter, req *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(code)
if len(allow) > 0 {
w.Write([]byte(`Allow: ` + strings.Join(allow, ", ")))
}
}
}
func APIUsers(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("hello"))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论