はじめに
この記事では、Goを使用してJSON形式のデータする方法について解説します。標準ライブラリであるencoding/json
パッケージを使用して、Gonoデータ構造とJSON形式のデータを相互に変換する方法をサンプルコードを用いて説明します。
想定読者
- Go構造体 <-> JSON形式の変換方法を知りたい駆け出しGopher
- Goの構造体型への基本的な理解
- JSONが何かわかる
記事の狙い
- Go言語におけるJSONのエンコードとデコードの基本的な使い方を理解する
結論
- 構造体タグを使ってJSONオブジェクトのフィールドとGo構造体のフィールドをマッチングする
-
json
というタグ名を使ってJSONフィールドを指定する
-
// 構造体タグを使ったフィールド名の指定
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
Email string `json:"email"`
}
- JSONエンコード(Go構造体 -> JSON形式)
-
Marshal
関数を使う
-
- JSONデコード(JSON形式 -> Go構造体)
-
Unmarshal
関数を使う
-
encoding/json
Goの標準ライブラリであるencoding/json
ライブラリはGoのデータ型とJSON間で相互に変換する機能を持っています。
- Goのデータ型からJSON形式への変換は マーシャリング(marshaling) と呼ばれる
- JSON形式からGoのデータ型への変換は アンマーシャリング(unmarshaling) と呼ばれる
構造体タグを使ったメタデータの付加
構造体タグを使うことで、JSON形式のデータとGoのデータ型の対応付けを行うことができます。構造体タグのルールは以下のようになっています。
- 構造体タグはバッククォート(`)で囲まれた文字列として定義される
- 構造体タグが行を跨ぐことはない
- `json:"key"`の形式でキー名を指定する
type Person struct {
Name string `json:"name"` // `Name`フィールドはJSONのキー名が`name`になる
}
- フィールドが空の場合に、出力に含めたくない場合はキー名のあとに
,omitempty
をつける。マーシャリング時(JSON -> Go構造体)の時だけ適用されるため、アンマーシャリング時にはomitempty
タグは無視され、JSONデータからすべてのフィールドが構造体フィールドに変換される
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
Address string `json:"address,omitempty"` // Addressが空の場合JSON出力から除外される
}
- キー名の前にハイフンをつけることで、マーシャリングの際にJSON出力から除外される。アンマーシャリング時にはハイフンは無視され、JSONデータに含まれているフィールドは対応する構造体フィールドに変換される(値はゼロ値が設定される)
type Person struct {
Name string `json:"name"`
Email string `json:"-"` // EmailフィールドはJSON出力に含まれない
}
マーシャリングとアンマーシャリング
ここからは、具体的なコード例を交えてJSONのエンコードとデコードの方法を見ていきたいと思います。
マーシャリング(JSONエンコード)
Goの構造体型をJSON形式に変換するためMarchal
関数を使います。
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
Address string `json:"address,omitempty"`
}
func main() {
// Personインスタンスを作成
p := Person{
Name: "John Doe",
Age: 30,
}
// PersonインスタンスをJSONに変換
b, err := json.Marshal(p)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(b))
}
上記のコードを実行すると、以下のようなJSON出力が得られます。,omitempty
オプションを指定しているAddress
フィールドは空であるため出力されていないことが分かります。
{
"name": "John Doe",
"age": 30
}
アンマーシャリング(JSONデコード)
JSON形式のデータをGoの構造体に変換するためUnmarshal
関数を使用します。
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"-"`
Address string `json:"address,omitempty"`
}
func main() {
// JSONデータ
jsonData := `{"name":"John","age":0}`
// Personインスタンスを生成
var p Person
// JSONデータをPersonインスタンスに変換
err := json.Unmarshal([]byte(jsonData), &p)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%+v\n", p)
}
上記のコードを実行すると、以下のような出力が得られます。Age
フィールドにはハイフンを設定していますが、アンマーシャリングのため、対応するフィールドに変換されゼロ値が設定させています。Address
フィールドについては、JSONに対応するフィールドが存在しませんが、出力にはAddress
フィールドが設定されていることが分かります。
{Name:John Age:0 Address:}
まとめ
この記事では、Go言語を使ってJSONデータと構造体の相互変換を行う方法について解説しました。標準ライブラリであるencoding/jsonパッケージを使用して、エンコード(マーシャリング)とデコード(アンマーシャリング)の基本的な使い方を説明しました。以下に主要なポイントをまとめます。
- マーシャリング (Go構造体 -> JSON形式):
-
Marshal
関数を使用して、Go構造体をJSON形式に変換する - 構造体タグに
json:"fieldname,omitempty"
を付けることで、ゼロ値のフィールドをJSON出力から省略できる -
json:"-"
タグを付けたフィールドは、マーシャリングの際に常に出力から除外される
-
- アンマーシャリング (JSON形式 -> Go構造体):
-
Unmarshal
関数を使用して、JSONデータをGo構造体に変換する -
omitempty
タグはアンマーシャリング時には無視され、JSONデータに含まれるすべてのフィールドが対応する構造体フィールドに変換される -
json:"-"
タグを付けたフィールドは、アンマーシャリング時には無視され、JSONデータに含まれるフィールドは対応する構造体フィールドに変換される(値はゼロ値が設定される)
-