Home >Backend Development >Golang >How to Partially Decode and Update JSON Objects in Go?

How to Partially Decode and Update JSON Objects in Go?

Barbara Streisand
Barbara StreisandOriginal
2024-12-25 00:29:16859browse

How to Partially Decode and Update JSON Objects in Go?

Partial JSON Decoding and Updating in Go

In certain scenarios, a common problem arises when decoding and updating only specific values of a JSON object, especially when the complete object structure is unknown. The standard encoding/json package in Go truncates fields not provided in the struct, leading to data loss.

Solution using json.RawMessage

A solution to this problem is to combine a custom struct with json.RawMessage. This approach allows us to preserve the entire data into a raw field for encoding/decoding.

The json.RawMessage type in Go is a []byte value that can hold arbitrary JSON data. It is useful for cases like this, where we know only part of the JSON structure and want to preserve the unknown portions.

Example Code

package main

import (
    "encoding/json"
    "log"
)

type Color struct {
    Space string
    raw   map[string]json.RawMessage
}

func (c *Color) UnmarshalJSON(bytes []byte) error {
    if err := json.Unmarshal(bytes, &c.raw); err != nil {
        return err
    }
    if space, ok := c.raw["Space"]; ok {
        if err := json.Unmarshal(space, &c.Space); err != nil {
            return err
        }
    }
    return nil
}

func (c *Color) MarshalJSON() ([]byte, error) {
    bytes, err := json.Marshal(c.Space)
    if err != nil {
        return nil, err
    }
    c.raw["Space"] = json.RawMessage(bytes)
    return json.Marshal(c.raw)
}

func main() {
    before := []byte(`{"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}}`)
    log.Println("before: ", string(before))

    // decode
    color := new(Color)
    err := json.Unmarshal(before, color)
    if err != nil {
        log.Fatal(err)
    }

    // modify fields of interest
    color.Space = "RGB"

    // encode
    after, err := json.Marshal(color)
    if err != nil {
        log.Fatal(err)
    }
    log.Println("after:  ", string(after))
}

Output

before:  {"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}}
after:   {"Point":{"Y":255,"Cb":0,"Cr":-10},"Space":"RGB"}

This solution allows us to decode and update only a specific value (in this case, Space) while preserving all other unknown data in the JSON object. It is important to note that this approach does not preserve key order or indentations in the output.

The above is the detailed content of How to Partially Decode and Update JSON Objects in Go?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn