jsongotype-conversionunmarshalling

json string to uint64 convert workaround


I'm currently trying to use json.Unmarshal to convert a json response from server into a type struct.

Part of my type struct uses a type from a library (https://pkg.go.dev/github.com/clarkzjw/starlink-grpc-golang@v1.0.20250818/pkg/spacex.com/api/device#WifiConfig) that contains the 50+ fields from the json response, which I am obviously not going to reinvent from scratch.

My issue is that for one of their fields, they expect uint64, but json converted this to a string in the response.

Incarnation uint64    `protobuf:"varint,43,opt,name=incarnation,proto3" json:"incarnation,omitempty"`

Field in json:

{
    ...,
    "incarnation": "11111111111111111",
    ...
}

The struct fails to include ,string in its json formatting, and as a result I'm getting the error:

json: cannot unmarshal string into Go struct field WifiConfig.wifiGetStatus.config.incarnation of type uint64

Is there a way around this without needing to build my own 50+ field type struct? Or like is there a way to use a custom logic that when we expect a uint64, we convert the json field from json to uint64 before proceeding with normal unmarshal behavior.

I'm currently just using the simple workaround of unmarshaling the json into a map, but we would like to not use this approach if possible.


Solution

  • Can you switch to the protojson decoder? This is what I usually reach for when dealing with JSON encoded gRPC messages. It supports this scenario.

    msg := foo.ConfigMessage{}
    data := []byte(`{"incarnation":"11111111111111111"}`)
    fmt.Printf("%v\n", json.Unmarshal(data, &msg))      // json: cannot unmarshal...
    fmt.Printf("%v\n", protojson.Unmarshal(data, &msg)) // <nil>
    fmt.Printf("%v\n", msg.Incarnation)                 // 11111111111111111