Golang Echo分别绑定path param和json body

ilmyapht  于 2023-08-01  发布在  Go
关注(0)|答案(2)|浏览(111)

我在Golang中使用Echo Web框架,并编写了以下代码

package main

import (
    "github.com/labstack/echo/v4"
    "net/http"
)

type ProjectPath struct {
    ID string `param:"id"`
}

type ProjectBody struct {
    Name string `json:"name"`
}

func main() {
    e := echo.New()

    e.POST("/project/:id", getProjectHandler)

    e.Start(":8080")
}

func getProjectHandler(c echo.Context) error {
    path := new(ProjectPath)
    if err := c.Bind(path); err != nil {
        return err
    }

    body := new(ProjectBody)
    if err := c.Bind(body); err != nil {
        return err
    }

    // Access the fields separately
    projectID := path.ID
    projectName := body.Name

    // Do something with the path and body fields...

    // Return a response
    return c.String(http.StatusOK, "Project ID: "+projectID+", Project Name: "+projectName)
}

字符串
我试图在post请求中分别绑定路径参数和json主体,但在尝试运行时出现EOF错误。
我正在使用replit进行测试,服务器运行在:第一个月
curl 后请求:

curl -X POST https://echotest.sandeepacharya.repl.co/project/123 -H "Content-Type: application/json" -d '{"name":"Sandeep"}'


回复:

{"message":"EOF"}

mzillmmw

mzillmmw1#

如果你想单独进行绑定,那么你需要使用 * 源代码特定的 * 绑定方法。然而,这些方法在上下文中不可用,而是由DefaultBinder实现。
另见:https://echo.labstack.com/guide/binding/#direct-source

func getProjectHandler(c echo.Context) error {
    path := new(ProjectPath)
    if err := (&echo.DefaultBinder{}).BindPathParams(c, path); err != nil {
        return err
    }

    body := new(ProjectBody)
    if err := (&echo.DefaultBinder{}).BindBody(c, body); err != nil {
        return err
    }

    // Access the fields separately
    projectID := path.ID
    projectName := body.Name

    // Do something with the path and body fields...

    // Return a response
    return c.String(http.StatusOK, "Project ID: "+projectID+", Project Name: "+projectName)
}

字符串

am46iovg

am46iovg2#

Bind()直接从套接字读取请求体,一旦读取就不能再次读取,因此出现EOF错误
https://github.com/labstack/echo/issues/782#issuecomment-317503513
出现此问题的原因是您尝试绑定请求正文两次。第二个c.Bind()将引发错误,因为请求体已经被读取和使用。
如果你想用不同的结构体读取请求,你可以遵循这种方法

package main

import (
    "fmt"
    "net/http"

    "github.com/labstack/echo/v4"
)

type ProjectPath struct {
    ID string `param:"id"`
}

type ProjectBody struct {
    Name string `json:"name"`
}

type ProjectRequest struct {
    ProjectPath
    ProjectBody
}

func main() {
    e := echo.New()

    e.POST("/project/:id", getProjectHandler)

    e.Start(":8080")
}

func getProjectHandler(c echo.Context) error {

    project := new(ProjectRequest)
    if err := c.Bind(project); err != nil {
        fmt.Println("Error happened due to::", err)
        return err
    }

    // Access the fields separately
    projectID := project.ID
    projectName := project.Name

    // Do something with the path and body fields...

    // Return a response
    return c.String(http.StatusOK, "Project ID: "+projectID+", Project Name: "+projectName)
}

字符串
也可以只使用一个结构来绑定请求

type ProjectRequest struct {
    Name string `json:"name"`
    ID string `param:"id"`
}

相关问题