REST上不受支持的HTTP方法返回什么响应代码?

REST上不受支持的HTTP方法返回什么响应代码?,rest,go,mux,gorilla,Rest,Go,Mux,Gorilla,我正在使用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) 然后我做这样的

我正在使用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 -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
tho,因为请求不是“
OK


关于这个主题有什么想法和提示吗?

您应该返回的状态代码是“405 MethodNotAllowed”或http.StatusMethodNowAllowed

来自维基百科:

使用不支持的请求方法对资源发出请求 利用该资源;例如,在需要数据的表单上使用GET 通过POST或在只读资源上使用PUT呈现


您应该返回的状态代码是“405 MethodNotAllowed”或http.StatusMethodNowAllowed

来自维基百科:

使用不支持的请求方法对资源发出请求 利用该资源;例如,在需要数据的表单上使用GET 通过POST或在只读资源上使用PUT呈现


您可以设置自定义的
NotFoundHandler
,但该设置将应用于所有不匹配的路由

如果希望返回特定响应,则必须明确定义路由

例如:

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"))
}

您可以设置自定义的
NotFoundHandler
,但这将应用于所有不匹配的路由

如果希望返回特定响应,则必须明确定义路由

例如:

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"))
}

谢谢你的回答,阿扬。RESTAPI也使用这种方法吗?不幸的是,如果我不能将405指向一个不允许的方法,那么方法约束将是无用的:如果可能,PIt通常是返回适当的HTTP响应代码的好主意。感谢Arjan的回答。RESTAPI也使用这种方法吗?不幸的是,如果我不能将405指向一个不允许的方法,那么Methods约束将是无用的:在可能的情况下,PIt通常是返回适当的HTTP响应代码的好主意。mux被设置为在路由不匹配时使用http.NotFoundHandler()。您是否为
路由器指定了NotFoundHandler
?您应该得到404。mux被设置为在路由不匹配时使用http.NotFoundHandler()。您是否为
路由器指定了NotFoundHandler
?感谢@jmaloney的回答。知道我如何从状态为(405)的HandleFunc访问这些方法吗?我想要实现的是将
Allow
设置成
Allow:GET,POST
作为405响应的信息。我丢失路由信息的当前方式(包含已设置的方法)。我应该保留一个全局缓冲区变量来跟踪它,还是可以用其他方法检测它?@Allender您只需将允许的方法传递到status函数中即可。我已经更新了我的答案来说明。谢谢@jmaloney。我最终在正常路由绑定的基础上得到了一个额外的helper函数,如下所示<代码>添加路径(“/users/{id:[0-9]+}/”,apiUsers,“GET”,“POST”,“PUT”)。这样,我还可以让更多的家长喜欢确定每条路由是否需要Auth/TLS/Etc。再次感谢:)谢谢你的回答@jmaloney。知道我如何从状态为(405)的HandleFunc访问这些方法吗?我想要实现的是将
Allow
设置成
Allow:GET,POST
作为405响应的信息。我丢失路由信息的当前方式(包含已设置的方法)。我应该保留一个全局缓冲区变量来跟踪它,还是可以用其他方法检测它?@Allender您只需将允许的方法传递到status函数中即可。我已经更新了我的答案来说明。谢谢@jmaloney。我最终在正常路由绑定的基础上得到了一个额外的helper函数,如下所示<代码>添加路径(“/users/{id:[0-9]+}/”,apiUsers,“GET”,“POST”,“PUT”)。这样,我还可以让更多的家长喜欢确定每条路由是否需要Auth/TLS/Etc。再次感谢:)