[BUG]`hero.Resulthandler` can only handle custom struct
- Dominant language
- Go
- Stars
- 25.6k
- Forks
- 2.4k
- PR merge metrics
- No merged PRs in 30d
Description
`hero.ResultHandler` can only handle cases where the return value is a custom struct or `dispatcher`. After reviewing the code, I found that before `ResultHandler` processing, it needs to go through `dispatchFuncResult` processing, and then `dispatchCommon` decides whether to call handlers. I would like to know why it was designed this way.
In scenarios where `Container` is used to uniformly handle return values, I hope that the return values of all `Handlers` are uniformly wrapped and processed, so that a unified return value structure can be obtained. However, the framework has specialized handling for some basic types, which forces me to call `ctx.JSON(map[string]interface{} {...})` in some handlers.
The code and expected result I hope to achieve is as follows:
```golang
type Response struct {
Code int `json:"code"`
Data interface{} `json:"data,omitempty"`
Msg string `json:"msg,omitempty"`
}
type testOutput struct {
ID int `json:"id"`
Name string `json:"name"`
}
func resultFormatter(next hero.ResultHandler) hero.ResultHandler {
return func(ctx iris.Context, v interface{}) error {
log.Infof("use result handler\n")
return next(ctx, map[string]interface{}{
"code": 200,
"data": v,
"msg": "",
})
}
}
func emptyResHandler(ctx iris.Context) {
log.Info("hello")
}
func boolResHandler(ctx iris.Context) bool {
return true
}
func stringResHandler(ctx iris.Context) string {
return "hello"
}
func intResHandler(ctx iris.Context) int {
return 1
}
func int64ResHandler(ctx iris.Context) int64 {
return 1
}
func structResHandler(ctx iris.Context) testOutput {
return testOutput{
ID: 1,
Name: "hello",
}
}
func configureApi(api *iris.APIContainer) {
api.UseResultHandler(resultFormatter)
api.Get("/empty", emptyResHandler)
api.Get("/bool", boolResHandler)
api.Get("/string", stringResHandler)
api.Get("/int", intResHandler)
api.Get("/int64", int64ResHandler)
api.Get("/struct", structResHandler)
}
```
when the return value is `empty`, the expected result is:
```json
{
"code": 200,
"data": null,
"msg": ""
}
```
when the return value is `string`, the expected result is:
```json
{
"code": 200,
"data": "string",
"msg": ""
}
```
when the return value is `custom struct`, the expected result is :
```json
{
"code": 200,
"data": {
"id": 1,
"name": "test"
},
"msg": ""
}
```
and so on...
Contributor guide
Research direction
Trace the ResultHandler flow through dispatchFuncResult and dispatchCommon, then inspect how APIContainer.UseResultHandler is applied to the listed empty, bool, string, integer, and struct handlers. Reproduce the examples and compare each response with the requested code/data/msg wrapper. Done means the formatter receives and can consistently wrap every handler return type, with tests covering the demonstrated cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100