英文:
How can I handle http requests of different methods to / in Go?
问题
我正在尝试找出在Go中处理对“/”和仅“/”的请求的最佳方法,并以不同的方式处理不同的方法。这是我想出的最好的方法:
package main
import (
"fmt"
"html"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
if r.Method == "GET" {
fmt.Fprintf(w, "GET, %q", html.EscapeString(r.URL.Path))
} else if r.Method == "POST" {
fmt.Fprintf(w, "POST, %q", html.EscapeString(r.URL.Path))
} else {
http.Error(w, "Invalid request method.", 405)
}
})
log.Fatal(http.ListenAndServe(":8080", nil))
}
这是Go的惯用写法吗?这是我在标准http库中能做的最好的吗?我更喜欢像express或Sinatra那样做一些类似http.HandleGet("/", handler)
的事情。有没有一个适合编写简单REST服务的好框架?web.go看起来很有吸引力,但似乎停滞不前。
谢谢你的建议。
英文:
I'm trying to figure out the best way to handle requests to /
and only /
in Go and handle different methods in different ways. Here's the best I've come up with:
package main
import (
"fmt"
"html"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
if r.Method == "GET" {
fmt.Fprintf(w, "GET, %q", html.EscapeString(r.URL.Path))
} else if r.Method == "POST" {
fmt.Fprintf(w, "POST, %q", html.EscapeString(r.URL.Path))
} else {
http.Error(w, "Invalid request method.", 405)
}
})
log.Fatal(http.ListenAndServe(":8080", nil))
}
Is this idiomatic Go? Is this the best I can do with the standard http lib? I'd much rather do something like http.HandleGet("/", handler)
as in express or Sinatra. Is there a good framework for writing simple REST services? web.go looks attractive but appears stagnant.
Thank you for your advice.
答案1
得分: 125
为了确保只提供根目录服务:你正在做正确的事情。在某些情况下,您可能希望调用http.FileServer对象的ServeHttp方法,而不是调用NotFound;这取决于您是否还有其他要提供的杂项文件。
为了以不同的方式处理不同的方法:我的许多HTTP处理程序只包含像这样的switch语句:
switch r.Method {
case http.MethodGet:
// 提供资源。
case http.MethodPost:
// 创建新记录。
case http.MethodPut:
// 更新现有记录。
case http.MethodDelete:
// 删除记录。
default:
http.Error(w, "不允许的方法", http.StatusMethodNotAllowed)
}
当然,您可能会发现像gorilla这样的第三方包对您更好。
英文:
To ensure that you only serve the root: You're doing the right thing. In some cases you would want to call the ServeHttp method of an http.FileServer object instead of calling NotFound; it depends whether you have miscellaneous files that you want to serve as well.
To handle different methods differently: Many of my HTTP handlers contain nothing but a switch statement like this:
switch r.Method {
case http.MethodGet:
// Serve the resource.
case http.MethodPost:
// Create a new record.
case http.MethodPut:
// Update an existing record.
case http.MethodDelete:
// Remove the record.
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
Of course, you may find that a third-party package like gorilla works better for you.
答案2
得分: 45
嗯,我实际上正准备睡觉,所以快速评论一下查看http://www.gorillatoolkit.org/pkg/mux,它非常好,并且可以做你想要的事情,只需查看文档。例如
func main() {
r := mux.NewRouter()
r.HandleFunc("/", HomeHandler)
r.HandleFunc("/products", ProductsHandler)
r.HandleFunc("/articles", ArticlesHandler)
http.Handle("/", r)
}
和
r.HandleFunc("/products", ProductsHandler).
Host("www.domain.com").
Methods("GET").
Schemes("http")
以及许多其他可能性和执行上述操作的方法。
但我觉得有必要解决问题的另一部分,“这是我能做的最好的吗”。如果标准库有点太简单,一个很好的资源可以查看这里:https://github.com/golang/go/wiki/Projects#web-libraries(特别链接到Web库)。
英文:
eh, I was actually heading to bed and thus the quick comment on looking at http://www.gorillatoolkit.org/pkg/mux which is really nice and does what you want, just give the docs a look over. For example
func main() {
r := mux.NewRouter()
r.HandleFunc("/", HomeHandler)
r.HandleFunc("/products", ProductsHandler)
r.HandleFunc("/articles", ArticlesHandler)
http.Handle("/", r)
}
and
r.HandleFunc("/products", ProductsHandler).
Host("www.domain.com").
Methods("GET").
Schemes("http")
and many other possibilities and ways to perform the above operations.
But I felt a need to address the other part of the question, "Is this the best I can do". If the std lib is a little too bare, a great resource to check out is here: https://github.com/golang/go/wiki/Projects#web-libraries (linked specifically to web libraries).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论