Go: Get path parameters from http.Request

huangapple go评论78阅读模式
英文:

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(&quot;/provisions/:id&quot;, Provisions) //&lt;-- How can I map &quot;id&quot; parameter in the path?
	http.ListenAndServe(&quot;:8080&quot;, nil)
}

func Provisions(w http.ResponseWriter, r *http.Request) {
    //I want to retrieve here &quot;id&quot; 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(&quot;/provisions/&quot;, Provisions)

Then split up the path as needed in the handler

id := strings.TrimPrefix(req.URL.Path, &quot;/provisions/&quot;)
// 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 (
    &quot;fmt&quot;
    &quot;github.com/gorilla/mux&quot;
    &quot;net/http&quot;
)

func main() {
    r := mux.NewRouter()
    r.HandleFunc(&quot;/provisions/{id}&quot;, Provisions)
    http.ListenAndServe(&quot;:8080&quot;, r)
}

func Provisions(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    id, ok := vars[&quot;id&quot;]
    if !ok {
	    fmt.Println(&quot;id is missing in parameters&quot;)
    }
    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(&quot;/api&quot;)
    {
        g.GET(&quot;/template/get/:Id&quot;, templates.TemplateGetIdHandler)
    }
    r.Run()
}

And use this function in handler

func TemplateGetIdHandler(c *gin.Context) {
	req := getParam(c, &quot;Id&quot;)
    //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(&quot;/api&quot;)
    {
        g.GET(&quot;/template/get&quot;, templates.TemplateGetIdHandler)
    }
    r.Run()
}

And use this function in handler

type TemplateRequest struct {
	Id string `form:&quot;id&quot;`
}

func TemplateGetIdHandler(c *gin.Context) {
    var request TemplateRequest
    err := c.Bind(&amp;request)
    if err != nil {
	    log.Println(err.Error())
	    c.JSON(http.StatusBadRequest, gin.H{&quot;error&quot;: 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 := &quot;/provisions/&quot;
  mux.Handle(
    provisionsPath,
    http.StripPrefix(provisionsPath, http.HandlerFunc(Provisions)),
  )
}

func Provisions(w http.ResponseWriter, r *http.Request) {
  fmt.Println(&quot;Provision ID:&quot;, 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.

huangapple
  • 本文由 发表于 2015年12月16日 22:45:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/34314975.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定