JSONを返す
構造体を JSON にする
Go
import "encoding/json"
item := Item{Name: "きのこ図鑑", Price: 1200}
b, err := json.Marshal(item)
string(b) // {"Name":"きのこ図鑑","Price":1200}Marshal が構造体を JSON のバイト列に変えます。第4章の形どおり、(値, error) を返します。
キー名が大文字で困る
出力を見ると、キーが Name と Price になっています。Go のフィールド名がそのまま出ているためです。
JSON の世界では小文字が普通なので、そのままでは使いにくくなります。構造体タグで指定します。
Go
type Item struct {
Name string `json:"name"`
Price int `json:"price"`
}プレーンテキスト
{"name":"きのこ図鑑","price":1200}フィールドの後ろにバッククォートで囲んで書くのがタグです。json.Marshal がこれを読んで、キー名を決めます。
小文字始まりのフィールドは出ない
第6章で触れた話が、ここで効いてきます。
Go
type Item struct {
Name string `json:"name"`
price int `json:"price"` // 出力されない
}json.Marshal は外から見えるフィールドしか読めません。小文字始まりは同じパッケージの中だけのものなので、対象外です。タグを書いても出ません。
「タグを書いたのに出ない」と悩んだら、まず頭文字を確かめてください。
空の値を省く
Go
type Item struct {
Name string `json:"name"`
Category string `json:"category,omitempty"`
}omitempty を付けると、ゼロ値のときにキーごと省かれます。
プレーンテキスト
Category が "" のとき {"name":"きのこ図鑑"}
Category が "本" のとき {"name":"きのこ図鑑","category":"本"}第2章のゼロ値がここでも顔を出します。「値が空」と「キーが無い」を区別する API では、この挙動が問題になることもあります。
応答として返す
Go
func itemHandler(w http.ResponseWriter, r *http.Request) {
item := Item{Name: "きのこ図鑑", Price: 1200}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(item)
}NewEncoder(w).Encode(...) は、Marshal して w に書くところまでを1行でやります。応答を返すときはこちらが定番です。
Content-Type を書くのは、受け取る側に JSON だと伝えるためです。ヘッダは本文より先に書きます。WriteHeader と同じ順序の決まりです。
なお Encode は末尾に改行を付けます。この挙動は覚えておいてください。応答を1文字単位で比べるときに引っかかります。
要件
Itemの3つのフィールドに構造体タグを付ける- キー名は name・price・category
json.Marshalで変換してw.Writeで書く- 本文だけを返す
入出力例
itemJSON("きのこ図鑑", 1200, "本") → "{"name":"きのこ図鑑","price":1200,"category":"本"}"
itemJSON("中古スマホ", 24800, "家電") → "{"name":"中古スマホ","price":24800,"category":"家電"}"
itemJSON("おまけ", 0, "その他") → "{"name":"おまけ","price":0,"category":"その他"}"ヒント
編集 ゆめさく編集部