golangの日記

Go言語を中心にプログラミングについてのブログ

JSONをもとにGo言語の構造体を自動生成できるjson-to-go.js

golang.png


encoding/jsonでJSONをGo言語の構造体にマッピングするには
当然、そのデータのプロパティ名と値の型を構造体で定義しておく必要がある。
大規模なJSONの場合だとその作業は大変なのでjson-to-goを使って構造体の定義を自動生成する。





Webツールとして公開されているので、以下のページにブラウザでアクセスして変換することも可能。
https://mholt.github.io/json-to-go/


ダウンロード

ローカルで実行するには json-to-go から json-to-go.js をダウンロード

$ curl -sSO https://raw.githubusercontent.com/mholt/json-to-go/master/json-to-go.js


実行

stdinからデータを渡す。

$ cat input.json | node ./json-to-go.js > output.go


  • input.json
{
  "string": "hello",
  "integer": 10,
  "float": 10.5,
  "boolean": true,
  "null": null,
  "array": [
    10,
    20,
    30
  ],
  "object-parent": {
    "child-1": 10,
    "child-2": {
      "string": "hello"
    }
  },
  "object-in-array": [
    { "foo": 10 },
    { "bar": 20 },
    { "baz": 30 }
  ],
  "space in key": 10,
  "snake_case": 10
}


  • output.go
type AutoGenerated struct {
    String string `json:"string"`
    Integer int `json:"integer"`
    Float float64 `json:"float"`
    Boolean bool `json:"boolean"`
    Null interface{} `json:"null"`
    Array []int `json:"array"`
    ObjectParent ObjectParent `json:"object-parent"`
    ObjectInArray []ObjectInArray `json:"object-in-array"`
    SpaceInKey int `json:"space in key"`
    SnakeCase int `json:"snake_case"`
}
type Child2 struct {
    String string `json:"string"`
}
type ObjectParent struct {
    Child1 int `json:"child-1"`
    Child2 Child2 `json:"child-2"`
}
type ObjectInArray struct {
    Foo int `json:"foo,omitempty"`
    Bar int `json:"bar,omitempty"`
    Baz int `json:"baz,omitempty"`
}


  • デフォルトではネストしたオブジェクトはそれぞれ構造体として分割される。
  • プロパティ名の 空白、_- などは削除されてキャメルケースになる。
  • デフォルトでは全体を表す構造体の名前は AutoGenerated になる。
  • null は interface{}になる。
  • 配列の値がオブジェクトだったら omitempty(プロパティ名がJSONになくてもよい)になる。
  • json-to-go.js 内を map で検索してもヒットしないので、
    型が map[string]interface{} のようなことにはならないっぽい。



全体の構造体名の指定や、分割せずにひとつの構造体としてまとめるには
json-to-go.js 内の最後のほうにある jsonToGo(json).go の引数を書き換える。

  • 第二引数: 全体の構造体名を指定する。(先頭が小文字でも大文字で出力される)
  • 第三引数: 構造体を分離せずにひとつにまとめる。デフォルトは true なので、false を指定する
jsonToGo(json, "structureName", false).go


実行

$ cat input.json | node ./json-to-go.js > output.go


結果

type StructureName struct {
    String string `json:"string"`
    Integer int `json:"integer"`
    Float float64 `json:"float"`
    Boolean bool `json:"boolean"`
    Null interface{} `json:"null"`
    Array []int `json:"array"`
    ObjectParent struct {
        Child1 int `json:"child-1"`
        Child2 struct {
            String string `json:"string"`
        } `json:"child-2"`
    } `json:"object-parent"`
    ObjectInArray []struct {
        Foo int `json:"foo,omitempty"`
        Bar int `json:"bar,omitempty"`
        Baz int `json:"baz,omitempty"`
    } `json:"object-in-array"`
    SpaceInKey int `json:"space in key"`
    SnakeCase int `json:"snake_case"`
}