Unmarshal map in struct in golang

Issue

I have a go proto file here. I have defined a struct that I would like to unmarshal using the golang json package.

package main

import (
    "bytes"
    "encoding/json"
    "fmt"

    gw "github.com/kserve/rest-proxy/gen"
)

type REST struct {
    Id         string                                             `json:"id,omitempty"`
    Parameters map[string]*gw.InferParameter                      `json:"parameters,omitempty"`
    Inputs     []*gw.ModelInferRequest_InferInputTensor           `json:"inputs,omitempty"`
    Outputs    []*gw.ModelInferRequest_InferRequestedOutputTensor `json:"outputs,omitempty"`
}

func main() {
    d := REST{}
    buffer := &bytes.Buffer{}
    data := `
    {
        "id": "1",
        "inputs": [{
            "name": "input:0",
            "shape": [-1, -1, -1, -1],
            "datatype": "UINT8",
            "parameters": {
                "binary_data_size": {
                    "int64Param": 100
                }
            }
        }]
    }
    `
    buffer.Write([]byte(data))
    if err := json.NewDecoder(buffer).Decode(&d); err != nil {
        fmt.Println(err)
    }
    fmt.Println(d)
}
{1 map[] [name:"input:0" datatype:"UINT8" shape:-1 shape:-1 shape:-1 shape:-1 parameters:{key:"binary_data_size" value:{}}] []}

May I know how to get binary_data_size value which should be 100. Is my JSON schema incorrect ? Thank you.

Solution

The standard encoding/json package "does not operate correctly on protocol buffer messages" (source; also see this issue for more info). There are ways of working around this but using google.golang.org/protobuf/encoding/protojson is the recommended approach – i.e.:

package main

import (
    "fmt"

    gw "github.com/kserve/rest-proxy/gen"
    "google.golang.org/protobuf/encoding/protojson"
)

func main() {
    d := gw.ModelInferRequest{}
    data := []byte(`
{
    "id": "1",
    "inputs": [{
        "name": "input:0",
        "shape": [-1, -1, -1, -1],
        "datatype": "UINT8",
        "parameters": {
            "binary_data_size": {
                "int64Param": 100
            }
        }
    }]
}`)

    if err := protojson.Unmarshal(data, &d); err != nil {
        panic(err)
    }
    fmt.Println(d)
}

Result:

{{{} [] [] 0xc00013ecd0} 0 []   1 map[] [name:"input:0" datatype:"UINT8" shape:-1 shape:-1 shape:-1 shape:-1 parameters:{key:"binary_data_size" value:{int64_param:100}}] [] []}

Answered By – Brits

Answer Checked By – David Goodson (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.