[golang(Go言語)]json入門
APIサーバーでは、jsonを用いてデータのやり取りをすることが多いと思います。今回はjsonの基本的な使い方について、ご紹介します。
構造体とjson
リクエストとして受け取ったjsonを取り扱うために、golangではjsonを構造体に変換します。
ここでは、json変換の為の構造体定義を紹介します。main.goは下のコードのまま変えず、構造体の記述の違いによって出力される値(構造体を変換したjson)がどう変化するか、見ていきます。
package main import ( "encoding/json" "fmt" "json/domain/model" ) func main() { u := model.User{ Name: "james", } s, _ := json.Marshal(&u) fmt.Print(string(s)) }
基本
package model type User struct { Name string Age int }
まず構造体は、このままでもjsonに変換することは可能です。この構造体をjsonに変換した場合、json内でのフィールド名は構造体のフィールド名と同じになります。
$ go run main.go {"Name":"james","Age":0}
jsonタグでフィールド名を指定する
type User struct { Name string `json:"name"` Age int `json:""` }
jsonタグを用いて、自由にjsonフィールド名を指定できます。タグを付けつつフィールド名を指定しないという無意味なことも可能で、フィールド名はそのままです。
$ go run main.go {"name":"james","Age":0}
omitemptyか-でフィールドを除外する
type User struct { Name string `json:"-"` Age int `json:"age,omitempty"` }
jsonフィールド名を-にすると、フィールドの値がどうであろうと変換時に無視されます。
,omitemptyを付けると、フィールドの値がゼロ値の場合そのフィールドが構造体から除外されます。フィールド名を指定せず",omitempty"だけでも可です。
$ go run main.go {}
Marhal 構造体→json
u := model.User{ Name: "james", } s, _ := json.Marshal(&u) fmt.Print(string(s))
構造体のポインタが引数、[]byteとerrorが戻り値です。なおMarshlには1つだけ注意事項があるので記載します。
var u *model.User
s, _ := json.Marshal(u)
このように記述してしまうと、コンパイルエラーにはなりませんが、panicが発生します。原因は、Marshlの引数にnilを渡してしまっているからです。ポインタ型をvarで宣言する際は気をつけてください。
Unmarshal json→構造体
u := model.User{ Name: "james", } s, _ := json.Marshal(&u) fmt.Println(string(s)) n := model.User{} _ = json.Unmarshal(s, &n) fmt.Printf("%+v", n)
Unmarshalでも、構造体のポインタを引数にしています。
出力結果は、フィールドが何も指定されていないのでゼロ値になります。
$ go run main.go {} {Name: Age:0}