
GoでJSONデータ扱う方法を知りたいな…
WEBアプリ開発においてJSONデータの扱いは必須でしょう。
では、Go言語でJSONデータを扱うにはどうしたらよいのでしょうか?
今回はGoの標準パッケージ・encoding/json
を使用してJSONから構造体、構造体からJSONのデータを変換する方法をお伝えしていきます。
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データにする
今回のプログラムでは、age
が int
で型指定しています。
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
と構造体の T
を omitempty
指定してみましょう。
// 構造体のデータが空の場合は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":{}}

あれっ!?構造体の 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
のポイントを解説いたしますね!
JSONデータで取得したデータの項目を気にすることなく、あなたがアプリ開発で必要とするデータを構造体で定義することで不必要なデータは除外されます。
取得したJSONデータを加工することなく使用できます。
【まとめ】GoのプログラムでJSONデータを扱う
今回はGoの標準パッケージ・encoding/json
を使用してJSONデータの活用についてお伝えしてきました。
それでは、今までの内容をまとめましょう。
以上です。
今回はJSONデータをGoのプログラムで扱う際の基本についてお伝えしていきました。
JSONはWEBアプリ開発をしていく上で重要な位置づけにありますから、まずは基本から理解していきましょう。
comment