問9 JSONで応答せよ
師範 / 目安 35分
「HTTP の世界に出ます」
凛さんが仕様書を開きました。「GET /items。Item 一覧を JSON で返すハンドラを。フィールド名は Node版と同じ小文字でお願いします。互換が命のリプレイスですから」
Go のハンドラは、決まった形をした関数です。
Go
func handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(items)
}w が応答を書く先、r が届いたリクエストです。Express の res と req に対応します。
ここで互換の落とし穴があります。Go の構造体で外から見えるフィールドは、大文字始まりでなければいけません。ところが JSON にすると、その大文字がそのまま出ます。
Go
type Item struct {
Name string
}
// → {"Name":"レザースニーカー"} Node版は {"name":...} なのに解決するのが構造体タグです。フィールドの後ろに、逆引用符で囲んだ指定を添えます。
Go
type Item struct {
ID int `json:"id"`
Name string `json:"name"`
}これで {"id":1,"name":"レザースニーカー"} になります。タグ1つで互換が守れます。
動作を確かめるには httptest を使います。本物のサーバーを立てずにハンドラを呼び、応答を取り出せます。
Go
rec := httptest.NewRecorder()
handler(rec, httptest.NewRequest("GET", "/items", nil))
res := rec.Result()完成条件
商品一覧を JSON で返すハンドラと、それを確かめる関数を作ってください。
Item 構造体には ID と Name と Price を持たせ、JSON では id name price という小文字の名前で出します。
serveItems は商品一覧を用意して httptest でハンドラを呼び、次の形の1行を返してください。引数の extra が true のときは商品を2件にします。
プレーンテキスト
200|application/json|[{"id":1,"name":"レザースニーカー","price":4800}]ステータスコード、Content-Type の値、本文を縦棒で区切ります。Encode は末尾に改行を付けるので、そこは取り除いてください。
この問題は net/http を使うので、最初の実行だけ 15 秒ほどかかります。時間切れになったらもう一度実行してください。2回目からは速くなります。
要件
Itemに構造体タグを付け、JSON のキーをidnamepriceにする- ハンドラで
Content-Typeにapplication/jsonを設定し、一覧を JSON で書き出す httptestでハンドラを呼び、ステータス|Content-Type|本文の形で返す(本文末尾の改行は除く)
入出力例
serveItems(false) → "200|application/json|[{"id":1,"name":"レザースニーカー","price":4800}]"
serveItems(true) → "200|application/json|[{"id":1,"name":"レザースニーカー","price":4800},{"id":2,"name":"木製のスツール","price":3500}]"ヒント
前のヒントを開くと次が開きます。開かずに解けると未開封クリアです