Golang Unmarshal an JSON response, then marshal with Struct field names

Issue

So I am hitting an API that returns a JSON response and I am unmarshalling it into a struct like so:

package main



type ProcessedRecords struct {
    SLMIndividualID                  string      `json:"individual_id"`
    HouseholdPosition                int         `json:"Household Position"`
    IndividualFirstName              string      `json:"individual_first_name"`
}

func main() {
    req, _ := http.NewRequest(method, url, payload)

    res, err := client.Do(req)
    if err != nil {
        fmt.Println(err)
    }
    defer res.Body.Close()
    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Println(err)
    }
    
    fmt.Println(body)
    
    var responseObject Response
    json.Unmarshal(body, &responseObject)
    fmt.Println(responseObject)

which works great. However I need to marshal this struct again but I want to use the Struct Fields as keys instead of the json: ... fields. I am using the following code:

    recordsInput := []*firehose.Record{}
    for i := 0; i < len(records); i++ {
        if len(recordsInput) == 500 {
            * code to submit records, this part works fine *
        }

        b, err := json.Marshal(records[i])

        if err != nil {
            log.Printf("Error: %v", err)
        }

        record := &firehose.Record{Data: b}
        recordsInput = append(recordsInput, record)
    }

This does submit records successfully but it’s in the format:

{"individual_id":"33c05b49-149b-480f-b1c2-3a3b30e0cb6f","Household Position":1...}

and I’d like it in the format:

{"SLMIndividualId":"33c05b49-149b-480f-b1c2-3a3b30e0cb6f","HouseholdPosition":1...}

How can I achieve this?

Solution

Those tags say how the struct should be marshalled, so if they are present, that is how the output will be. You’ll need to convert it to a matching struct that does not have the json: tags:

type ProcessedRecords struct {
    SLMIndividualID     string `json:"individual_id"`
    HouseholdPosition   int    `json:"Household Position"`
    IndividualFirstName string `json:"individual_first_name"`
}

type ProcessedRecordsOut struct {
    SLMIndividualID     string
    HouseholdPosition   int
    IndividualFirstName string
}

func process() {
    var in ProcessedRecords
    json.Unmarshal(data, &in)
    // Convert to same type w/o tags
    out := ProcessedRecordsOut(in)
    payload, _ := json.Marshal(out)
    // ...
}

See a working example here: https://play.golang.org/p/p0Fc8DJotYE

Answered By – Adrian

Answer Checked By – Dawn Plyler (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.