Go:从http.Request获取路径参数

问题描述 投票:0回答:5

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

我想要这样的东西:

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
}

如果可能的话,我想只使用

http
包而不是 Web 框架。

谢谢。

http go rest http-parameters
5个回答
75
投票

如果您不想使用众多可用路由包中的任何一个,那么您需要自己解析路径:

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

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

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

id := strings.TrimPrefix(req.URL.Path, "/provisions/")
// or use strings.Split, or use regexp, etc.

21
投票

您可以使用 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 is missing in parameters")
    }
    fmt.Println(`id := `, id)
    //call http://localhost:8080/provisions/someId in your browser
    //Output : id := someId
}

3
投票

Golang 从 URL 查询“/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")
    //your stuff
}

func getParam(c *gin.Context, paramName string) string {
    return c.Params.ByName(paramName)
}

Golang 从 URL 查询“/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()})
    }
    //your stuff
}

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


0
投票

如果您使用的是 Go 1.22,您可以使用

r.PathValue()
轻松检索路径参数。例如:

package main

import (
    "fmt"
    "net/http"
    "net/http/httptest"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/provisions/{id}", func(w http.ResponseWriter, r *http.Request) {
        fmt.Println("Provision ID: ", r.PathValue("id"))
    })

    mux.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest("GET", "/provisions/123", nil))
    mux.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest("GET", "/provisions/456", nil))
}

Go Playground中进行演示。来源:https://pkg.go.dev/net/http#Request.PathValue

© www.soinside.com 2019 - 2024. All rights reserved.