kataras / kataras/iris

[BUG]`hero.Resulthandler` can only handle custom struct

Open
#2,448 2 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.