英文:
Go: Get path parameters from http.Request
问题
我正在使用Go开发一个REST API,但我不知道如何进行路径映射并从中获取路径参数。
我想要实现类似这样的功能:
func main() {
http.HandleFunc("/provisions/:id", Provisions) // <-- 我该如何映射路径中的"id"参数?
http.ListenAndServe(":8080", nil)
}
func Provisions(w http.ResponseWriter, r *http.Request) {
// 我想要从请求中获取"id"参数
}
如果可能的话,我希望只使用http
包,而不是Web框架。
谢谢。
英文:
I'm developing a REST API with Go, but I don't know how can I do the path mappings and retrieve the path parameters from them.
I want something like this:
func main() {
http.HandleFunc("/provisions/:id", Provisions) //<-- How can I map "id" parameter in the path?
http.ListenAndServe(":8080", nil)
}
func Provisions(w http.ResponseWriter, r *http.Request) {
//I want to retrieve here "id" parameter from request
}
I would like to use just http
package instead of web frameworks, if it is possible.
Thanks.
答案1
得分: 69
如果您不想使用现有的众多路由包之一,那么您需要自己解析路径:
将路径"/provisions"路由到您的处理程序:
http.HandleFunc("/provisions/", Provisions)
然后在处理程序中根据需要拆分路径:
id := strings.TrimPrefix(req.URL.Path, "/provisions/")
// 或者使用strings.Split,或者使用正则表达式等。
英文:
If you don't want to use any of the multitude of the available routing packages, then you need to parse the path yourself:
Route the /provisions path to your handler
http.HandleFunc("/provisions/", Provisions)
Then split up the path as needed in the handler
id := strings.TrimPrefix(req.URL.Path, "/provisions/")
// or use strings.Split, or use regexp, etc.
答案2
得分: 15
你可以使用golang的gorilla/mux包的路由器来进行路径映射并从中获取路径参数。
import (
"fmt"
"github.com/gorilla/mux"
"net/http"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/provisions/{id}", Provisions)
http.ListenAndServe(":8080", r)
}
func Provisions(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, ok := vars["id"]
if !ok {
fmt.Println("参数中缺少id")
}
fmt.Println("id := ", id)
// 在浏览器中调用 http://localhost:8080/provisions/someId
// 输出: id := someId
}
你可以使用gorilla/mux包的路由器来处理路径映射和获取路径参数。
英文:
You can use golang gorilla/mux package's router to do the path mappings and retrieve the path parameters from them.
import (
"fmt"
"github.com/gorilla/mux"
"net/http"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/provisions/{id}", Provisions)
http.ListenAndServe(":8080", r)
}
func Provisions(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, ok := vars["id"]
if !ok {
fmt.Println("id is missing in parameters")
}
fmt.Println(`id := `, id)
//call http://localhost:8080/provisions/someId in your browser
//Output : id := someId
}
答案3
得分: 3
从URL查询中读取Golang的值"/template/get/123"。
我使用了标准的gin路由和从上下文参数处理请求参数。
在注册端点时使用以下代码:
func main() {
r := gin.Default()
g := r.Group("/api")
{
g.GET("/template/get/:Id", templates.TemplateGetIdHandler)
}
r.Run()
}
在处理程序中使用以下函数:
func TemplateGetIdHandler(c *gin.Context) {
req := getParam(c, "Id")
// 进行你的操作
}
func getParam(c *gin.Context, paramName string) string {
return c.Params.ByName(paramName)
}
从URL查询中读取Golang的值"/template/get?id=123"。
在注册端点时使用以下代码:
func main() {
r := gin.Default()
g := r.Group("/api")
{
g.GET("/template/get", templates.TemplateGetIdHandler)
}
r.Run()
}
在处理程序中使用以下结构体和函数:
type TemplateRequest struct {
Id string `form:"id"`
}
func TemplateGetIdHandler(c *gin.Context) {
var request TemplateRequest
err := c.Bind(&request)
if err != nil {
log.Println(err.Error())
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
// 进行你的操作
}
英文:
Golang read value from URL query "/template/get/123".
I used standard gin routing and handling request parameters from context parameters.
Use this in registering your endpoint:
func main() {
r := gin.Default()
g := r.Group("/api")
{
g.GET("/template/get/:Id", templates.TemplateGetIdHandler)
}
r.Run()
}
And use this function in handler
func TemplateGetIdHandler(c *gin.Context) {
req := getParam(c, "Id")
//your stuff
}
func getParam(c *gin.Context, paramName string) string {
return c.Params.ByName(paramName)
}
Golang read value from URL query "/template/get?id=123".
Use this in registering your endpoint:
func main() {
r := gin.Default()
g := r.Group("/api")
{
g.GET("/template/get", templates.TemplateGetIdHandler)
}
r.Run()
}
And use this function in handler
type TemplateRequest struct {
Id string `form:"id"`
}
func TemplateGetIdHandler(c *gin.Context) {
var request TemplateRequest
err := c.Bind(&request)
if err != nil {
log.Println(err.Error())
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
//your stuff
}
答案4
得分: 3
你可以使用标准库的处理程序来实现这个功能。注意,http.StripPrefix
接受一个http.Handler
并返回一个新的处理程序:
func main() {
mux := http.NewServeMux()
provisionsPath := "/provisions/"
mux.Handle(
provisionsPath,
http.StripPrefix(provisionsPath, http.HandlerFunc(Provisions)),
)
}
func Provisions(w http.ResponseWriter, r *http.Request) {
fmt.Println("Provision ID:", r.URL.Path)
}
在Go playground上可以看到工作示例。
你也可以使用子路由来嵌套这种行为;http.ServeMux
实现了http.Handler
接口,所以你可以将一个子路由传递给http.StripPrefix
。
英文:
You can do this with standard library handlers. Note http.StripPrefix
accepts an http.Handler
and returns a new one:
func main() {
mux := http.NewServeMux()
provisionsPath := "/provisions/"
mux.Handle(
provisionsPath,
http.StripPrefix(provisionsPath, http.HandlerFunc(Provisions)),
)
}
func Provisions(w http.ResponseWriter, r *http.Request) {
fmt.Println("Provision ID:", r.URL.Path)
}
See working demo on Go playground.
You can also nest this behavior using submuxes; http.ServeMux
implements http.Handler
, so you can pass one into http.StripPrefix
just the same.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论