GoのJSON構造体タグでomitemptyを使う
Goのomitemptyタグオプションをマスターし、JSON出力に表示されるフィールドを制御します。ゼロ値、ポインタセマンティクス、よくある落とし穴を解説。
Struct Tags
詳細な説明
Goのomitemptyタグ
omitempty オプションは、GoのJSONエンコーダーにフィールドがゼロ値の場合にスキップするよう指示します。これにより、よりクリーンで小さなJSON出力が生成されます。
型ごとのゼロ値
| 型 | ゼロ値 |
|---|---|
string |
"" |
int, float64 |
0 |
bool |
false |
| ポインタ | nil |
| スライス、マップ | nil(空ではない) |
| 構造体 | 省略されない |
例
type User struct {
Name string `json:"name"`
Email string `json:"email,omitempty"`
Age int `json:"age,omitempty"`
Verified bool `json:"verified,omitempty"`
Bio *string `json:"bio,omitempty"`
}
Email が ""、Age が 0、Verified が false の場合、マーシャリングの結果:
{ "name": "Alice" }
boolとゼロの落とし穴
よくある間違い:false や 0 がドメインで有効な値の場合(例:正当に false になりうるboolフラグ)、omitempty はそれらを隠してしまいます。解決策はポインタ型を使うことです:
Verified *bool `json:"verified,omitempty"`
これにより、nil は「未提供」を意味し省略されますが、false は有効な値として含まれます。
構造体は省略されない
構造体フィールドに omitempty を付けても効果はありません — 空の構造体 {} は常に含まれます。省略動作が必要な場合は構造体へのポインタを使用します:
Address *Address `json:"address,omitempty"`
omitemptyを使うべき場面
PATCHリクエストのオプショナルフィールド、スパースなレスポンスオブジェクト、フィールドの不在が意味を持つ場所で使用します。ゼロが有効で意味のある値であるフィールドでは避けてください。
ユースケース
REST APIのPATCHエンドポイントは変更されたフィールドのみを送信することが多いです。リクエスト構造体にomitemptyを使うことで、未変更のフィールドがJSONボディに含まれず、意図しない上書きを防ぎます。