6
4

Goのjson.Marshalで非公開フィールドも出力する方法

Last updated at Posted at 2024-09-09

背景

こんにちは。エンジニアのKennieです。
以前の業務で、非公開フィールドを持つ構造体をシリアライズする必要がありました。その際にデフォルトでのMarshalJsonではシリアライズすることができなかったので、その際に学んだことを記載します。

デフォルトのMarshalJsonを使用したコード例

まずは、Goのデフォルトの MarshalJSON を使ったシンプルなコード例を見てみましょう。以下のコードでは、公開フィールドを持つ構造体がJSONとしてシリアライズされています。

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Name string
	Age  int
}

func main() {
	p := Person{Name: "Alice", Age: 30}
	data, err := json.Marshal(p)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println(string(data))
}

出力結果

{"Name":"Alice","Age":30}

Ageを非公開にした場合

type Person struct {
	Name string
	age  int
}

出力結果

{"Name":"Alice"}

このように、非公開フィールドはデフォルトのシリアライズ処理では無視されます。

非公開フィールドをシリアライズするためのカスタム MarshalJSON

非公開フィールドは、デフォルトの MarshalJSON ではシリアライズされません。そのため、カスタムの MarshalJSON を実装する必要があります。

package main

import (
	"encoding/json"
	"fmt"
)

type person struct {
	Name string
	age  int // 非公開フィールド
}

func (p person) MarshalJSON() ([]byte, error) {
	return json.Marshal(struct {
		Name string `json:"Name"`
		Age  int    `json:"Age"`
	}{
		Name: p.Name,
		Age:  p.age,
	})
}

func main() {
	p := person{Name: "Alice", age: 30}
	data, err := json.Marshal(p)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println(string(data))
}

出力結果

{"Name":"Alice","Age":30}

ここでは age フィールドが非公開ですが、MarshalJSON メソッドをカスタム実装することで、非公開フィールドであっても JSON 出力に含めることができます。

実行の流れ

  1. json.Marshal の呼び出し: json.Marshal 関数が呼ばれ、Person 構造体のインスタンスがシリアライズされます。これは Person 型のデータをJSON形式に変換するための関数です。

  2. MarshalJSON のチェック: json.Marshal は Person 構造体が json.Marshaler インターフェースを実装しているかどうかを確認します。

  3. カスタムメソッドの呼び出し: Person 構造体が json.Marshaler インターフェースを実装している場合、MarshalJSON メソッドが呼び出されます。このメソッドが返す結果がJSONとして出力されます。デフォルトのシリアライズ処理は無視され、Person 型に実装されたカスタムの MarshalJSON メソッドによるシリアライズが適用されます。

終わりに

開発の際に非公開フィールドを含む構造体をシリアライズする必要がありましたが、デフォルトの MarshalJSON メソッドではこれを実現できませんでした。そのため、カスタムの MarshalJSON メソッドを実装することで、非公開フィールドにアクセスし、シリアライズを行うことができました。今回の経験を通じて、MarshalJSON メソッドを用いたシリアライズ処理について理解が深まりました。

6
4
1

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
6
4