Go: Get path parameters from http.Request

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

Go: Get path parameters from http.Request

问题

我正在使用Go开发一个REST API,但我不知道如何进行路径映射并从中获取路径参数。

我想要实现类似这样的功能:

  1. func main() {
  2. http.HandleFunc("/provisions/:id", Provisions) // <-- 我该如何映射路径中的"id"参数?
  3. http.ListenAndServe(":8080", nil)
  4. }
  5. func Provisions(w http.ResponseWriter, r *http.Request) {
  6. // 我想要从请求中获取"id"参数
  7. }

如果可能的话,我希望只使用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:

  1. func main() {
  2. http.HandleFunc(&quot;/provisions/:id&quot;, Provisions) //&lt;-- How can I map &quot;id&quot; parameter in the path?
  3. http.ListenAndServe(&quot;:8080&quot;, nil)
  4. }
  5. func Provisions(w http.ResponseWriter, r *http.Request) {
  6. //I want to retrieve here &quot;id&quot; parameter from request
  7. }

I would like to use just http package instead of web frameworks, if it is possible.

Thanks.

答案1

得分: 69

如果您不想使用现有的众多路由包之一,那么您需要自己解析路径:

将路径"/provisions"路由到您的处理程序:

  1. http.HandleFunc("/provisions/", Provisions)

然后在处理程序中根据需要拆分路径:

  1. id := strings.TrimPrefix(req.URL.Path, "/provisions/")
  2. // 或者使用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

  1. http.HandleFunc(&quot;/provisions/&quot;, Provisions)

Then split up the path as needed in the handler

  1. id := strings.TrimPrefix(req.URL.Path, &quot;/provisions/&quot;)
  2. // or use strings.Split, or use regexp, etc.

答案2

得分: 15

你可以使用golang的gorilla/mux包的路由器来进行路径映射并从中获取路径参数。

  1. import (
  2. "fmt"
  3. "github.com/gorilla/mux"
  4. "net/http"
  5. )
  6. func main() {
  7. r := mux.NewRouter()
  8. r.HandleFunc("/provisions/{id}", Provisions)
  9. http.ListenAndServe(":8080", r)
  10. }
  11. func Provisions(w http.ResponseWriter, r *http.Request) {
  12. vars := mux.Vars(r)
  13. id, ok := vars["id"]
  14. if !ok {
  15. fmt.Println("参数中缺少id")
  16. }
  17. fmt.Println("id := ", id)
  18. // 在浏览器中调用 http://localhost:8080/provisions/someId
  19. // 输出: id := someId
  20. }

你可以使用gorilla/mux包的路由器来处理路径映射和获取路径参数。

英文:

You can use golang gorilla/mux package's router to do the path mappings and retrieve the path parameters from them.

  1. import (
  2. &quot;fmt&quot;
  3. &quot;github.com/gorilla/mux&quot;
  4. &quot;net/http&quot;
  5. )
  6. func main() {
  7. r := mux.NewRouter()
  8. r.HandleFunc(&quot;/provisions/{id}&quot;, Provisions)
  9. http.ListenAndServe(&quot;:8080&quot;, r)
  10. }
  11. func Provisions(w http.ResponseWriter, r *http.Request) {
  12. vars := mux.Vars(r)
  13. id, ok := vars[&quot;id&quot;]
  14. if !ok {
  15. fmt.Println(&quot;id is missing in parameters&quot;)
  16. }
  17. fmt.Println(`id := `, id)
  18. //call http://localhost:8080/provisions/someId in your browser
  19. //Output : id := someId
  20. }

答案3

得分: 3

从URL查询中读取Golang的值"/template/get/123"。

我使用了标准的gin路由和从上下文参数处理请求参数。

在注册端点时使用以下代码:

  1. func main() {
  2. r := gin.Default()
  3. g := r.Group("/api")
  4. {
  5. g.GET("/template/get/:Id", templates.TemplateGetIdHandler)
  6. }
  7. r.Run()
  8. }

在处理程序中使用以下函数:

  1. func TemplateGetIdHandler(c *gin.Context) {
  2. req := getParam(c, "Id")
  3. // 进行你的操作
  4. }
  5. func getParam(c *gin.Context, paramName string) string {
  6. return c.Params.ByName(paramName)
  7. }

从URL查询中读取Golang的值"/template/get?id=123"。

在注册端点时使用以下代码:

  1. func main() {
  2. r := gin.Default()
  3. g := r.Group("/api")
  4. {
  5. g.GET("/template/get", templates.TemplateGetIdHandler)
  6. }
  7. r.Run()
  8. }

在处理程序中使用以下结构体和函数:

  1. type TemplateRequest struct {
  2. Id string `form:"id"`
  3. }
  4. func TemplateGetIdHandler(c *gin.Context) {
  5. var request TemplateRequest
  6. err := c.Bind(&request)
  7. if err != nil {
  8. log.Println(err.Error())
  9. c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  10. }
  11. // 进行你的操作
  12. }
英文:

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:

  1. func main() {
  2. r := gin.Default()
  3. g := r.Group(&quot;/api&quot;)
  4. {
  5. g.GET(&quot;/template/get/:Id&quot;, templates.TemplateGetIdHandler)
  6. }
  7. r.Run()
  8. }

And use this function in handler

  1. func TemplateGetIdHandler(c *gin.Context) {
  2. req := getParam(c, &quot;Id&quot;)
  3. //your stuff
  4. }
  5. func getParam(c *gin.Context, paramName string) string {
  6. return c.Params.ByName(paramName)
  7. }

Golang read value from URL query "/template/get?id=123".

Use this in registering your endpoint:

  1. func main() {
  2. r := gin.Default()
  3. g := r.Group(&quot;/api&quot;)
  4. {
  5. g.GET(&quot;/template/get&quot;, templates.TemplateGetIdHandler)
  6. }
  7. r.Run()
  8. }

And use this function in handler

  1. type TemplateRequest struct {
  2. Id string `form:&quot;id&quot;`
  3. }
  4. func TemplateGetIdHandler(c *gin.Context) {
  5. var request TemplateRequest
  6. err := c.Bind(&amp;request)
  7. if err != nil {
  8. log.Println(err.Error())
  9. c.JSON(http.StatusBadRequest, gin.H{&quot;error&quot;: err.Error()})
  10. }
  11. //your stuff
  12. }

答案4

得分: 3

你可以使用标准库的处理程序来实现这个功能。注意,http.StripPrefix接受一个http.Handler并返回一个新的处理程序:

  1. func main() {
  2. mux := http.NewServeMux()
  3. provisionsPath := "/provisions/"
  4. mux.Handle(
  5. provisionsPath,
  6. http.StripPrefix(provisionsPath, http.HandlerFunc(Provisions)),
  7. )
  8. }
  9. func Provisions(w http.ResponseWriter, r *http.Request) {
  10. fmt.Println("Provision ID:", r.URL.Path)
  11. }

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:

  1. func main() {
  2. mux := http.NewServeMux()
  3. provisionsPath := &quot;/provisions/&quot;
  4. mux.Handle(
  5. provisionsPath,
  6. http.StripPrefix(provisionsPath, http.HandlerFunc(Provisions)),
  7. )
  8. }
  9. func Provisions(w http.ResponseWriter, r *http.Request) {
  10. fmt.Println(&quot;Provision ID:&quot;, r.URL.Path)
  11. }

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:

确定