0

This is the code example:

func GetValue(c echo.Context) error {
    //other implementation details
    
    value, err := service.GetValue()
    if err != nil {
        return c.JSON(http.StatusBadRequest, errorresponse.Error(4003, err))
    }

    //if I set same value here, it works as expected
    //value.Value = []int8{48, 48, 48, 54, 54, 49, 56, 54, 32, 32, 32, 32, 32, 32, 32}

    return c.JSON(http.StatusOK, value)
}
 
//this is type service.GetValue() returns
type ValueGetResponse struct {
    Value     interface{}
    ValueType string
}

If I use the value which comes from service.GetValue() method, the API gives me a response like bellow. It converts it to a some kind of string which I don't know. When I check the value.Value property, the reflect.TypeOf(value.Value) says, it is a []int8 as type. Also the VSCode debugger approves it.

THE OBJECT USED IN REQUEST:

enter image description here

THE RESPONSE:

{
    "Value": "MDAwNjYxODYgICAgICAg",
    "ValueType": "[]uint8"
}

If I set expected value manually, it works as expected and I do not understand why the first one is not.

value.Value = []int8{48, 48, 48, 54, 54, 49, 56, 54, 32, 32, 32, 32, 32, 32, 32}

THE OBJECT USED IN REQUEST:

enter image description here

THE RESPONSE:

{
    "Value": [
        48,
        48,
        48,
        54,
        54,
        49,
        56,
        54,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32
    ],
    "ValueType": "[]uint8"
}
MenyT
  • 1,653
  • 1
  • 8
  • 19
Barış Velioğlu
  • 5,709
  • 15
  • 59
  • 105
  • 1
    `int8` & `uint8` aren't one and the same. Also `byte` is an alias of `uint8` so `[]uint8` is probably a byte slice. That means that `"MDAwNjYxODYgICAgICAg"` is the correct value, the slice of *int8s* is most probably *not*. – mkopriva Oct 05 '21 at 09:34
  • I missed that point. You seems right – Barış Velioğlu Oct 05 '21 at 09:35
  • Is there any way to get this value as array, not as string ?@mkopriva – Barış Velioğlu Oct 05 '21 at 09:36
  • 1
    You'd have to type-assert the `Value` field and then convert it to something that gets marshaled into the format that you want. E.g. https://play.golang.org/p/AjDYhlmN3R6 – mkopriva Oct 05 '21 at 09:55

1 Answers1

0

In Golang byte is alias for uint8 and when you use json.Marshal it returns []byte which is same type as your data. So when you receive this type of data it is translated to string.

You need to cast uint8 to other int type or implement Marshaler interface

Cast

bytes, err := service.GetValue()
value := make([]int8, 0)
for _, v := range bytes {
    value = append(value, int8(v))
}

Marshaler

type CustomType []uint8

func (u CustomType) MarshalJSON() ([]byte, error) {
    var result string
    if u == nil {
        result = "null"
    } else {
        result = strings.Join(strings.Fields(fmt.Sprintf("%d", u)), ",")
    }
    return []byte(result), nil
}

func GetValue(c echo.Context) error {
    var value CustomType
    bytes, err := service.GetValue()
    value = bytes

    return c.JSON(http.StatusOK, value)
}
MenyT
  • 1,653
  • 1
  • 8
  • 19