実務において、レスポンスとしてJSONを返却しているのですが、DBにないカラムを構造体に追加した状態でリリースするとレスポンスはどうなりますか?という質問を受けたため、これに回答するためにGolangの構造体がJSONにマッピングされる時にどういう挙動をするのか調べたため、備忘録として残すもの。
公開フィールドとして定義した場合
package main
import (
"encoding/json"
"fmt"
)
// User 構造体の定義
// フィールド名の最初を「大文字」で定義した場合は公開フィールドとなる。
type User struct {
Name string `json:"name"`
Age int `json:"age"`
Sex int `json:"sex"`
}
func main() {
user := User{
Name: "John Doe",
Age: 25,
Sex: 1,
}
// User構造体をJSONにマーシャル
jsonData, err := json.Marshal(user)
if err != nil {
fmt.Println("Error marshalling JSON:", err)
return
}
// マーシャルされたJSONデータを表示
fmt.Println(string(jsonData))
// 結果: {"name":"John Doe","age":25,"sex":1}
}
公開フィールドで定義してた場合は、JSONにマッピングされる。
非公開フィールドで定義した場合
package main
import (
"encoding/json"
"fmt"
)
// User 構造体の定義
// フィールド名の最初を「小文字」で定義した場合は公開フィールドとなる。
type User struct {
Name string `json:"name"`
age int `json:"age"`
sex int `json:"sex"`
}
func main() {
user := User{
Name: "John Doe",
age: 25,
sex: 1,
}
// User構造体をJSONにマーシャル
jsonData, err := json.Marshal(user)
if err != nil {
fmt.Println("Error marshalling JSON:", err)
return
}
// マーシャルされたJSONデータを表示
fmt.Println(string(jsonData))
// struct field age has json tag but is not exported(構造体フィールド age には json タグがありますが、エクスポートされません)
// struct field sex has json tag but is not exported(構造体フィールド sex には json タグがありますが、エクスポートされません)
// 結果: {"name":"John Doe"}
}
「struct field age has json tag but is not exported」というエラーは発生するが動作する。
また、公開フィールドのNameは表示されるが、非公開フィールドであるage及びsexについてはマッピングされていない。
jsonタグで出力を制御する場合
package main
import (
"encoding/json"
"fmt"
)
// User 構造体の定義
// 「jsonタグで"-"」と定義する
type User struct {
Name string `json:"name"`
Age int `json:"-"`
Sex int `json:"-"`
}
func main() {
user := User{
Name: "John Doe",
Age: 25,
Sex: 1,
}
// User構造体をJSONにマーシャル
jsonData, err := json.Marshal(user)
if err != nil {
fmt.Println("Error marshalling JSON:", err)
return
}
// マーシャルされたJSONデータを表示
fmt.Println(string(jsonData))
// 結果: {"name":"John Doe"}
}
json:"-"
というように定義すると公開フィールドで定義していてもJSONにマッピングされない。
まとめ
非公開フィールドもしくはjson:"-"で定義した場合はJSONにマッピングされないことがわかった。
個人的にはjson:"-"の方がわかりやすいと感じたため、JSONにマッピングさせたくないフィールドがある場合は、json:"-"を使用していきたいと感じた。
参考資料