LoginSignup
4
4

More than 5 years have passed since last update.

MarshalJSONを実装する

Last updated at Posted at 2017-06-12

encoding/json パッケージのMarshalJSON処理を実装する方法をメモ
このメソッドを実装すると、構造体をJSONに変換する際に、変換結果を変更することができる。

今回やりたかったのは、空のStructがプロパティとして埋め込まれている場合、そのプロパティは omitempty が効かない。

下記の場合、Group 構造体が User 構造体に埋め込まれているが、omitempty しても意味がない。

type (

    Group struct {
        Name string `json:,omitempty`
    }

    User struct {
        Group       Group       `json:",omitempty"`
        Name        string      `json:",omitempty"`
        Age         int         `json:",omitempty"`
        UpdatedAt   time.Time   `json:",omitempty"`
    }

)

func main() {
    u := User{
        Name: "Hoge太郎",
        Age: 31,
        UpdatedAt:time.Date(2017, 6, 1, 1, 0, 0, 0, time.UTC),
    }

    userJson, _ := json.Marshal(u)
    fmt.Println(string(userJson))
}

出力結果

{"Group":{"Name":""},"Name":"Hoge太郎","Age":31,"UpdatedAt":"2017-06-01T01:00:00Z"}

omitempty されず "Group":{"Name":""} が出力されてしまっている。
場合によっては害を及ぼす。

この場合、json.MarshalerUser 構造体に実装させ、MarshalJSON JSON用の構造体をメソッド内で再定義する。
ただし、全てのプロパティを定義するのは面倒なので、オリジナルの構造体を埋め組むが、エイリアスとして組み込まなければMarshalJSONメソッドが無限ループに陥ってしまう。

type (

    Group struct {
        Name string `json:,omitempty`
    }

    User struct {
        Group       Group       `json:",omitempty"`
        Name        string      `json:",omitempty"`
        Age         int         `json:",omitempty"`
        UpdatedAt   time.Time   `json:",omitempty"`
    }

)

// JSON化処理を変更する(encoding/json.Marshalerを実装)
func (u User) MarshalJSON()([]byte, error){
    type Alias User
    // 全く新しい構造体を定義
    // 全てのプロパティを定義するのは面倒なので、オリジナルの構造体を埋め組む
    // ただし、エイリアスとして組み込まなければMarshalJSONメソッドが無限ループに陥ってしまう
    return json.Marshal(&struct {
        Alias
        Group bool `json:",omitempty"`
    }{
        Alias: (Alias)(u),
    })
}

func main() {
    u := User{
        Name: "Hoge太郎",
        Age: 31,
        UpdatedAt:time.Date(2017, 6, 1, 1, 0, 0, 0, time.UTC),
    }

    userJson, _ := json.Marshal(u)
    fmt.Println(string(userJson))
}

出力結果

{"Name":"Hoge太郎","Age":31,"UpdatedAt":"2017-06-01T01:00:00Z"}

この方法を応用して、日付のフォーマットを変更したり、追加でプロパティを増やしたりもできる。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4