英文:
How to customize a response data from two handlers in single entrypoint go?
问题
我在我的应用程序中使用了echo框架,并且在单个入口点上使用两个处理程序构建响应时遇到了问题。
以下是示例代码:
type RespObject struct {
Message string `json:"message"`
}
func main() {
e := echo.New()
e.GET("/hello", handler, middle)
e.Logger.Fatal(e.Start(":3000"))
}
func handler(c echo.Context) error {
return c.JSON(http.StatusOK, RespObject{
Message: "Hello",
})
}
func middle(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
c.JSON(http.StatusOK, RespObject{
Message: "World",
})
return next(c)
}
}
发送请求后,我得到了以下响应:
curl localhost:3000/hello
{"message":"World"}
{"message":"Hello"}
我的目标是生成以下响应:
{"message":"Hello World"}
echo.Context具有实现ResponseWriter的Response结构体。
但是,ResponseWriter似乎是只写的协议。有没有办法在ResponseWriter中擦除和重建数据?
据我所见,存在两个问题:
1)在传递“middle”处理程序后从ResponseWriter读取数据。
2)在“handler”处理程序中擦除ResponseWriter中的数据并写入新数据。
在实际问题中,结构体的名称冲突并不重要。这是对两个不同的SCIM API的请求,并将其组合成响应。
英文:
I use echo framework in my app and i faced with issue to constuct response from two handler on single entrypoint.
There is example code
type RespObject struct {
Message string `json:"message"`
}
func main() {
e := echo.New()
e.GET("/hello", handler, middle)
e.Logger.Fatal(e.Start(":3000"))
}
func handler(c echo.Context) error {
return c.JSON(http.StatusOK, RespObject{
Message: "Hello",
})
}
func middle(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
c.JSON(http.StatusOK, RespObject{
Message: "World",
})
return next(c)
}
}
after request i got
curl localhost:3000/hello
{"message":"World"}
{"message":"Hello"}
My goal is make response
{"message":"Hello World"}
echo.Context has struct Response with implement ResponseWriter
But seems ResponseWriter is WriteOnly contract. Is there is a way to some how erase and rebuild data in ResponseWriter?
As far i see there is a two issues
- Read data from ResponseWriter after passing "middle" handler.
- Erase data in ResponseWriter and write new data in "handler" handler
In real issue there is not necessary of name collision of struct. It`s request in two different SCIM API and make combine response.
答案1
得分: 3
这可以通过创建一个自定义函数来实现,该函数将响应对象和代码添加到上下文中,并在处理程序中调用它;在中间件中,您可以从上下文中获取此对象,修改响应并调用实际的c.JSON,将修改后的响应写入网络。
const (
echoCtxRespKey = "echo_ctx_resp_key"
)
type RespObject struct {
Message string `json:"message"`
}
type Response struct {
Data interface{}
Code int
}
func main() {
e := echo.New()
e.GET("/hello", handler, middle)
e.Logger.Fatal(e.Start(":3000"))
}
func handler(c echo.Context) error {
resp := RespObject{
Message: "Hello",
}
addResponseToContext(c, Response{
Data: resp,
Code: http.StatusOK,
})
return nil
}
func middle(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
next(c)
resp := getResponseFromContext(c)
// modify resp
return c.JSON(resp.Code, resp.Data)
}
}
func addResponseToContext(c echo.Context, response Response) {
c.Set(echoCtxRespKey, response)
}
func getResponseFromContext(c echo.Context) Response {
return c.Get(echoCtxRespKey).(Response)
}
以上是您提供的代码的翻译。
英文:
This can be achieved by creating a custom function that adds the response object and code to context and call it in handler; in middleware you get this object from context, modify the response and call actual c.JSON which writes the modified response to the wire.
const (
echoCtxRespKey = "echo_ctx_resp_key"
)
type RespObject struct {
Message string `json:"message"`
}
type Response struct {
Data interface{}
Code int
}
func main() {
e := echo.New()
e.GET("/hello", handler, middle)
e.Logger.Fatal(e.Start(":3000"))
}
func handler(c echo.Context) error {
resp := RespObject{
Message: "Hello",
}
addResponseToContext(c, Response{
Data: resp,
Code: http.StatusOK,
})
return nil
}
func middle(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
next(c)
resp := getResponseFromContext(c)
// modify resp
return c.JSON(resp.Code, resp.Data)
}
}
func addResponseToContext(c echo.Context, response Response) {
c.Set(echoCtxRespKey, response)
}
func getResponseFromContext(c echo.Context) Response {
return c.Get(echoCtxRespKey).(Response)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论