1. 小文字のキーで返る
  2. 2件でもキーは小文字のまま
コース一覧
Go道場 fleamaをGoで作り直す10問
問9 JSONで応答せよ

Go道場 fleamaをGoで作り直す10問

Go入門で身に付けた技を、商店街公式フリマアプリ「fleama」の Goリプレイス計画で試す演習専用コースです。解説はありません。依頼と完成条件だけを読み、白紙から自分で組み立てます。手が止まったときのために、方針・使う構文・部分解の3段階のヒントを各問に用意しています。ゼロ値の予言から始まり、error の受け止め方、for だけのループ、switch と定数、スライスとマップ、構造体とメソッド、ゴルーチンでの並行処理、JSON を返すハンドラを経て、最後は一覧・詳細・出品の3エンドポイントを Node版と互換になるよう組み上げるところまで、10問で Go の主要な道具を一巡します。1問15分から45分、全10問で約5時間です。Go入門を終えて「読めるけれど自分では書けない」と感じている方に向いています。

1
Goリプレイス計画
01. 問1 ゼロ値を予言せよ15分
02. 問2 errを無視するな20分
03. 問3 forしかない世界で集計せよ20分
04. 問4 商品状態で出し分けろ20分
05. 問5 スライスを育てよ25分
06. 問6 マップで在庫台帳25分
07. 問7 Itemに魂を込めよ30分
08. 問8 3本同時に走らせろ35分
09. 問9 JSONで応答せよ35分
10. 問10 総合 リプレイス完遂45分

問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回目からは速くなります。

要件

  1. Item に構造体タグを付け、JSON のキーを id name price にする
  2. ハンドラで Content-Type に application/json を設定し、一覧を JSON で書き出す
  3. 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}]"

ヒント

前のヒントを開くと次が開きます。開かずに解けると未開封クリアです

初期コードはタグが無いので、キーが `ID` `Name` `Price` の大文字で出てしまいます

ヒント 2ヒント 1 を開くと読めます
ヒント 3ヒント 2 を開くと読めます
生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/08/10

関連レッスン

  • 問10 総合 リプレイス完遂

    一覧・詳細・出品の3エンドポイントを、Node版と互換になるよう組み上げます。

  • 問8 3本同時に走らせろ

    3カテゴリの集計を goroutine で同時に走らせ、チャネルで回収します。

  • 問7 Itemに魂を込めよ

    構造体とメソッド、そして不正な商品を生ませないコンストラクタを書きます。

  • 問6 マップで在庫台帳

    カンマokイディオムで、存在しないカテゴリを聞かれても事故らない台帳にします。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • HTTPWeb の通信プロトコル、HTTPS は TLS で暗号化したもの
  • applicationJSON 本文を送るときの Content-Type
  • フィールドクラスが持つデータ
  • 関数処理に名前を付けて再利用できる単位
  • リクエストWeb 通信の基本単位、ブラウザの問い合わせとサーバーの返答
  • サーバークライアント(ブラウザなど)がリクエストを送り、サーバーがレスポンスを返す。
  • 引数位置引数=順番で渡す。
  • ステータスコード200/201/404 など結果を示す3桁の数値
main.go
学習モード
エディタを読み込んでいます

メモ

問9 JSONで応答せよ

⌘S で保存