Posted at

GoでJSONを雑に書く

テストのフィクスチャなどで、JSONを雑に書きたくなることがあるのだけど、

文字列で定義するとJSONとしての構文チェックができず不便だ。trailing commaとか、クオートの不備とかを気にして書かなくてはいけない。

js := `{

"baa": {
"a": 1,
"b": 1.9,
"c": "abc"
},
"foo": {
"baa": "muu",
"bababa": "gagaga"
}
}`

なので、Goとして構造を定義して、json.Marshal()したくなる。

https://golang.org/pkg/encoding/json/

json.Marshalは構造体を渡すことも多いが、雑に map[string]interface{} を渡しても動作する。これを使って書いていくとよい。


tips



  • map[string]interface{}だと長いので、適当に型を定義して使うと便利。


  • json.Marshalはエラーが発生する可能性があるが、自分でコード中で定義したjson構造がバグってたらどうしようもないので、エラーをpanic化してしまう雑な関数を定義してしまうのも便利。


  • json.Indentでインデントするのもいいぞ


  • []bytesで扱うか string で扱うかは状況によるので適宜切り替えてください。

package main

import (
"bytes"
"encoding/json"
"fmt"
)

type object map[string]interface{}
type oo map[string]object

func MustJsonString(obj interface{}) string {
b, err := json.Marshal(obj)
if err != nil {
panic(err)
}
var out bytes.Buffer
err = json.Indent(&out, b, "", " ")
if err != nil {
panic(err)
}
return out.String()
}

func main() {
js := oo{
"foo": {
"baa": "muu",
"bababa": "gagaga",
},
"baa": {
"a": 1,
"b": 1.9,
"c": "abc",
},
}
fmt.Println(MustJsonString(js))
}