JSONをGoの標準パッケージencoding/jsonで扱う

Go言語
この記事は約11分で読めます。
Go初学者
Go初学者

GoでJSONデータ扱う方法を知りたいな…

この記事ではGoでJSONデータを扱う方法を理解できます!
  • JSONとは?
  • 構造体のデータをJSONデータに変換する方法について
  • JSONデータを構造体のデータに変換する方法について

WEBアプリ開発においてJSONデータの扱いは必須でしょう。

では、Go言語でJSONデータを扱うにはどうしたらよいのでしょうか?

今回はGoの標準パッケージ・encoding/json を使用してJSONから構造体、構造体からJSONのデータを変換する方法をお伝えしていきます。

もりぴ
この記事を書いた人

XHTML1.0時代にHTML&CSSを勉強した経験あり。無趣味だった私が2020年5月からプログラミング学習を開始し現在も挫折せずに趣味で学習を楽しんでいる51歳。プログラミングの楽しさをブログを通してお伝えしていきます。

もりぴをフォローする

JSONとは?

JSONはJavaScript Object Notationの略で軽量なテキストベースのデータ書式であることが特徴で、JavaScriptのオブジェクトを作成する時の表記方法です。

ここまでJSONが扱われるようになったのは、WEB開発でフロント(ユーザーからの見た目の部分)でJavaScriptで開発、サーバー側はPHPやPython、Goで開発した場合のデータをやり取りする時に同じデータ書式でのやり取りが楽という背景があるからでしょう。

WEB上でデータを配布する形式でもJSON形式で配布されていますから、WEBアプリ開発では避けては通れないデータ書式です。

GoでJSONを扱おう!

Go言語でJSONを扱うために標準パッケージで、encoding/json が用意されています。

それでは、実際にプログラムを見ながら確認していきましょう。

Marshal・構造体のデータをJSON形式に変換する

Goの構造体のデータをJSON形式のデータに変換します。

ここで使用されるのが json.Marshal() です。

// Marshal・構造体のデータをJSON形式に変換する
package main

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

type T struct{}

type User struct {
    Name string
    Age  int
    T    T
}

func main() {
    // Marshal 構造体のデータをJSON形式に変換
    u := new(User)
    u.Name = "morip"
    u.Age = 51

    // mjは[]byteを受け取る
    mj, err := json.Marshal(u)
    if err != nil {
	log.Fatal(err)
    }
    fmt.Println(string(mj))
}
// 出力結果
$ go run main.go
{"Name":"morip","Age":51,"T":null}
もりぴ
もりぴ

JSONデータに変換されました!

JSONの書式に合わせて出力する

通常JSONデータはKeyの値が小文字になりますので、構造体を宣言する時にひと手間加えます。

// JSONの書式に合わせて出力する
package main

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

type T struct{}

// リテラルでエンコード内容を記述
type User struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
    T    T      `json:"t"`
}

func main() {
    u := new(User)
    u.Name = "morip"
    u.Age = 51

    mj, err := json.Marshal(u)
    if err != nil {
	log.Fatal(err)
    }
    fmt.Println(string(mj))
}
// 出力結果
$ go run main.go
{"name":"morip","age":51,"t":null}

全て小文字にエンコードされたことが確認できます。

構造体の定義で各フィールドの横に json:"name"` で囲むことでエンコードすることができます。

このエンコードですが、いろいろな指定をすることができます。

型を変換してJSONデータにする

今回のプログラムでは、ageint で型指定しています。

string として型を変換してJSONデータにすることもできますので、プログラムで確認していきましょう。

// 型を変換してJSONデータにする
package main

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

type T struct{}

// リテラルでエンコード内容を記述
type User struct {
    Name string `json:"name"`
    Age  int    `json:"age,string"`  // stringでデータ作成
    T    T      `json:"t"`
}

func main() {
    u := new(User)
    u.Name = "morip"
    u.Age = 51

    mj, err := json.Marshal(u)
    if err != nil {
	log.Fatal(err)
    }
    fmt.Println(string(mj))
}
// 出力結果
$ go run main.go
{"name":"morip","age":"51","t":null}

"age":"51"string でJSONデータが作成されています。

構造体の任意のデータを隠してJSON形式にデータを変換する

構造体の全てのデータをJSONデータに変換するのではなく、一部のデータは隠したい時の設定方法があります。

今回は Name を除いてJSONデータに変換しましょう。

// 構造体の任意のデータを隠してJSON形式にデータを変換
package main

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

type T struct{}

// リテラルでエンコード内容を記述
// 隠したいデータがある場合
type User struct {
    Name string `json:"-"`  // - で隠す
    Age  int    `json:"age,string"`
    T    T      `json:"t"`
}

func main() {
    u := new(User)
    u.Name = "morip"
    u.Age = 51

    mj, err := json.Marshal(u)
    if err != nil {
	log.Fatal(err)
    }
    fmt.Println(string(mj))
}
// 出力結果
$ go run main.go
{"age":"51","t":{}}

でKeyを指定することでJSONデータには変換されません。

構造体のデータが空の場合はJSONデータに変換しない

通常、構造体のデータが空の場合は型の初期値が代入されてJSONデータとして変換されます。

しかし、空のデータは表示をせずにJSONデータに変換する時は omitempty を使用します。

ここでは name と構造体の Tomitempty 指定してみましょう。

// 構造体のデータが空の場合はJSONデータに変換しない
package main

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

type T struct{}

// リテラルでエンコード内容を記述
// データが空の場合、表示しない omitempty
type User struct {
    Name string `json:"name,omitempty"`
    Age  int    `json:"age"`
    T    T      `json:"t,omitempty"`
}

func main() {
    u := new(User)
    u.Name = ""  // 値が空
    u.Age = 51

    mj, err := json.Marshal(u)
    if err != nil {
	log.Fatal(err)
    }
    fmt.Println(string(mj))
}
// 出力結果
$ go run main.go
{"age":"51","t":{}}
Go初学者
Go初学者

あれっ!?構造体の T は値が空なのに表示されていますよ。

もりぴ
もりぴ

構造体 T はポインタ型にする必要があります。

// 構造体のデータが空の場合はJSONデータに変換しない
package main

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

type T struct{}

// リテラルでエンコード内容を記述
// データが空の場合、表示しない omitempty
type User struct {
    Name string `json:"name,omitempty"`
    Age  int    `json:"age"`
    T    *T     `json:"t,omitempty"`  // ポインタ型へ
}

func main() {
    u := new(User)
    u.Name = ""  // 値が空
    u.Age = 51

    mj, err := json.Marshal(u)
    if err != nil {
	log.Fatal(err)
    }
    fmt.Println(string(mj))
}
// 出力結果
$ go run main.go
{"age":51}

Unmarshal・JSONデータを構造体の型に変換する

Unmarshal はJSONデータを構造体の型に変換することができます。

WEB上からJSONデータを取得して、Goのプログラムで利用する時に活用されます。

先程の Marshal したデータを元に Unmarshal してみましょう!

// 構造体のデータが空の場合はJSONデータに変換しない
package main

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

type T struct{}

type User struct {
    Name string `json:"name,omitempty"`
    Age  int    `json:"age"`
    T    *T     `json:"t,omitempty"`
}

func main() {
    u := new(User)
    u.Name = "morip" 
    u.Age = 51

    mj, err := json.Marshal(u)
    if err != nil {
	log.Fatal(err)
    }
    fmt.Println(string(mj))

    // Unmarshal
    // JSONのデータを構造体の型に変換
    u2 := new(User)

    if err := json.Unmarshal(mj, u2); err != nil {
	fmt.Println(err)
    }
    fmt.Println(u2.Name, u2.Age)
}
// 出力結果
$ go run main.go
{"name":"morip","age":51}
morip 51  // Unmarshalしたデータ

Unmarshal で変換したことにより構造体 u2 に値が代入されていることが確認できました。

もりぴ
もりぴ

Unmarshal のポイントを解説いたしますね!

Unmarshalのポイント
  • JSONデータは通常Keyは小文字(例えばname)だが、構造体で頭文字が大文字(今回はName)でも問題なく変換できる
  • JSONのデータに構造体で設定していない値は、構造体のフィールドに無ければ除外される

JSONデータで取得したデータの項目を気にすることなく、あなたがアプリ開発で必要とするデータを構造体で定義することで不必要なデータは除外されます。

取得したJSONデータを加工することなく使用できます。

【まとめ】GoのプログラムでJSONデータを扱う

今回はGoの標準パッケージ・encoding/json を使用してJSONデータの活用についてお伝えしてきました。

それでは、今までの内容をまとめましょう。

この記事で押さえておくポイント!
  • 構造体のデータをJSON形式に変換するには Marshal を使用する
  • JSONデータを構造体のデータとして変換するには Ummarshal を使用する
  • JSONの書式に合わせて出力するには ` で囲んで設定する
  • 構造体の任意のデータを隠してJSON形式にデータを変換するには で指定する
  • 構造体のデータが空の場合はJSONデータに変換しない場合は omitempty を指定する

以上です。

今回はJSONデータをGoのプログラムで扱う際の基本についてお伝えしていきました。

JSONはWEBアプリ開発をしていく上で重要な位置づけにありますから、まずは基本から理解していきましょう。

comment

タイトルとURLをコピーしました