【问题标题】:What Response Code to return on a non-supported HTTP Method on REST?在 REST 上不受支持的 HTTP 方法上返回什么响应代码?
【发布时间】:2015-02-26 22:54:53
【问题描述】:

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

关于这个主题的任何想法和提示?

【问题讨论】:

  • 你应该得到一个 404。当路由不匹配时,mux 设置为使用http.NotFoundHandler()。您是否为 Router 指定了 NotFoundHandler?

标签: rest go mux gorilla


【解决方案1】:

您可以设置自定义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"))
}

【讨论】:

  • 感谢@jmaloney 的回答。知道如何从状态(405)中的 HandleFunc 访问方法吗?我想要实现的是将导致Allow: GET,POSTAllow 设置为405 响应的信息。我丢失路线信息的当前方式(包含设置了哪些方法)。我应该保留一个全局缓冲区变量来跟踪它还是可以通过其他方式检测它?
  • @Allender 您可以将所需的允许方法传递给状态函数。我已经更新了我的答案来说明。
  • 谢谢@jmaloney。我终于在正常的路由绑定之上得到了一个额外的辅助函数,就像这样; addAPIRoute("/users/{id:[0-9]+}/", apiUsers, "GET", "POST", "PUT")。这样我也可以让更多的父母喜欢确定是否 Auth/TLS/Etc.每条路线都需要。再次感谢:)
【解决方案2】:

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

来自维基百科:

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

http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

【讨论】:

  • 感谢阿扬的回答。这对于 REST API 也很常见吗?可悲的是,如果我不能将 405 定向到不允许的方法,则方法约束将毫无用处:P
  • 在可能的情况下返回适当的 HTTP 响应代码通常是个好主意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-11
  • 1970-01-01
  • 1970-01-01
  • 2014-11-13
  • 2017-08-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多