コース一覧
    Go実践:並行処理とWeb API
    仕様互換を仕上げる

    Go実践:並行処理とWeb API

    Goの並行処理とWeb API開発を組み合わせ、実践的なサービス構築へ進むコースです。

    1
    ゴルーチンと並行処理のさわり
    01. ゴルーチン15分
    02. チャネル20分
    03. 待ち合わせ20分
    04. 並行の落とし穴20分
    05. つくる: 並行集計20分
    06. 第7章クイズ10分
    2
    Web API(net/http)
    01. サーバーを立てる20分
    02. ハンドラ関数20分
    03. JSONを返す20分
    04. ルーティング20分
    05. 一覧API20分
    06. 詳細APIと40420分
    07. 出品API20分
    08. つくる: API主要部完成25分
    09. 第8章クイズ10分
    3
    総合制作
    01. 仕様互換を仕上げる25分
    02. Node版と差し替える25分
    03. 1バイナリでデプロイ25分
    04. 自由拡張25分
    05. 完成と次のステップ20分

    仕様互換を仕上げる

    同じ仕様を、別の言語で満たす

    第9章でやるのは、実務でよくある仕事です。動いている API を、別の言語で作り直す。

    作り直すとき、中身は自由に書き換えられます。ですが外から見た振る舞いは1ミリも変えられません。使っている側は API の内側を知らないので、応答が少しでも違えば壊れます。

    プレーンテキスト

    変えてよい    使う言語、内部の構造、性能
    変えられない  URL、メソッド、応答の形、ステータスコード

    仕様書が正

    fleama API の仕様は次のとおりです。

    プレーンテキスト

    GET  /items          200  {"total":N,"items":[...]}
    GET  /items/{id}     200  {"id":..,"name":..,"price":..}
                         404  {"error":"not found"}
                         400  {"error":"invalid id"}
    POST /items          201  作成した商品
                         400  {"error":"理由"}
    それ以外のパス        404  {"error":"not found"}

    第8章で作ったものと1か所だけ違います。一覧が配列そのままではなく、total で包まれた形です。

    プレーンテキスト

    第8章    [{...},{...}]
    仕様書    {"total":2,"items":[{...},{...}]}

    第8章で「どちらが正しいということはない、ただし揃えること」と書きました。仕様書がある以上、こちらに合わせます。好みは関係ありません。

    包む形を作る

    専用の構造体を用意するのが素直です。

    Go

    type ListResponse struct {
    	Total int    `json:"total"`
    	Items []Item `json:"items"`
    }

    応答の形そのものを型にしておくと、キー名の付け忘れが起こりません。

    ここでも Items を nil のままにしないでください。0件のときに "items":null になります。仕様は [] です。

    登録していないパスも揃える

    第8章で触れたとおり、ServeMux の既定の 404 は page not found という文言です。仕様は JSON なので、これも揃えます。

    Go

    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    	writeError(w, 404, "not found")
    })

    / は前方一致なので、どのパスにも当てはまらなかったものがここへ来ます。より具体的な登録が優先されるので、/items などは奪われません。

    互換かどうかを測る

    「たぶん同じ」では作り直しになりません。同じリクエストを両方に投げて、応答が1文字単位で一致するかを確かめます。

    この演習のテストが、その突合そのものです。仕様書に書かれた応答を期待値に置いてあります。

    要件

    1. 一覧の応答を {"total":N,"items":[...]} の形にする
    2. 0件でも "items":[] を返す
    3. 登録していないパスに 404 {"error":"not found"} を返す
    4. 詳細と出品の振る舞いは変えない

    ヒント

    `ListResponse` 構造体を定義し、`Total` と `Items` にタグを付けます

    `listHandler` の `json.Marshal(result)` を `json.Marshal(ListResponse{Total: len(result), Items: result})` に変えます

    `mux.HandleFunc("/", ...)` を足すと、どの登録にも当てはまらないパスがそこへ来ます

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

    関連レッスン

    • Node版と差し替える

      同じ仕様の別実装に置き換えられることを確かめ、実務のリプレイスを疑似体験します。

    • 1バイナリでデプロイ

      go buildで作った1つのバイナリをサーバーに置き、常駐させる手順を説明できるようになります。

    • 自由拡張

      欲しいAPIを自分で設計して実装し、並行処理を活かした集計APIを1本作れるようになります。

    • 完成と次のステップ

      fleama-goの完成を確かめ、次に学ぶものを自分で選べるようになります。

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

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

    • エンドポイント「この URL を叩くとこの機能が動く」入口の住所
    • APIアプリ間でデータをやり取りする窓口
    • 配列サイズ固定の同型データの集まり
    • applicationJSON 本文を送るときの Content-Type
    • リクエストWeb 通信の基本単位、ブラウザの問い合わせとサーバーの返答
    • テストバグを見つける工程
    main.go
    エディタを読み込んでいます

    メモ

    仕様互換を仕上げる

    ⌘S で保存