Golang Echo 分别绑定路径参数和json body

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

我在 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进行测试,服务器运行在:

https://echotest.sandeepacharya.repl.co

卷曲发布请求:

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

回应:

{"message":"EOF"}
json go go-echo
2个回答
2
投票

如果您想单独进行绑定,那么您需要使用特定源绑定方法。然而,这些方法在上下文中不可用,而是由

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)
}

1
投票

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"`
}
© www.soinside.com 2019 - 2024. All rights reserved.