振り返りと改造課題
読了目安 約3分
完成したねじ板に Part 1〜4 の何が入っているかを振り返り、改造課題で理解を確かめます。
- 読む 部品を探す
- 改造する 1機能を変える
- 確かめる 通しで動かす
この章の目次
ねじ板は完成しました。 この章では手を動かす前に一度立ち止まり、作ったものの中に何が入っているかを眺めます。
この掲示板のどこに、どの Part が入っているか
Part 1 から Part 4 の道具をどこで使ったか、対応表にします。
| ねじ板の中でやったこと | 使った知識 |
|---|---|
| メソッドと URL の組で 7 つの機能を設計した | HTTP を生で読む |
| mux.HandleFunc で URL とハンドラを対応づけた | ルーティングとハンドラ |
| r.FormValue でフォームの値を受け取った | リクエストを受け取る |
| 401 や 409 を選んで返し、303 でリダイレクトした | レスポンスを返す |
| html/template で HTML を組み立てた | HTML と JSON |
| 投稿を Post という struct で表した | struct とメソッド |
| errors.Is と errors.As でエラーの種類を見分けた | エラー処理 |
| sessions の map を sync.Mutex で守った | goroutine と並行性 |
| CREATE TABLE と INSERT でデータを保存した | テーブルを作って書き込む |
| 一覧を SELECT と JOIN の 1 本のクエリで取った | SELECT でデータを取り出す、複数のテーブルと JOIN |
| database/sql と プレースホルダで Go から SQL を発行した | Go から SQL を使う |
- トランザクションは、複数の書き込みをひとまとめにする処理が無く出番なし(3 章の重複チェックは UNIQUE 制約に任せた)
- インデックスもこの規模では出番なし(Part 6 の主役の一つとして戻ってくる)
ISUCON で渡されるアプリを読むために
ISUCON で配られるお題のアプリは、このねじ板が数千行に育ったものだと考えてください。 URL は数十個、テーブルは十数個に増えますが、ハンドラが入力を受けて SQL を発行し、テンプレートか JSON で応答する構造は同じです。
初見のコードは、まずルーティングの定義から URL とハンドラの対応表を作り、次に CREATE TABLE の一覧を読みます。 1 章で自分がやった設計の逆再生です。
改造課題
改造課題を 3 つ置いておきます。 どれもこの Part の道具だけで作れます。
- 投稿の削除:自分の投稿にだけ削除ボタンを出し、POST /posts/{id}/delete で消せるようにしてください。パスの中の id は
r.PathValue("id")で取り出せます。URL を直接叩かれても他人の投稿を消せないように、DELETE 文の WHERE には id と user_id の両方を入れるのが要点です。 - ユーザーページ:GET /users/{id} で、そのユーザーの投稿だけの一覧を出してください。一覧のクエリに WHERE を足すだけで、テンプレートは index.html の作りが流用できます。
- 投稿数の表示:一覧の各投稿に「alice(12 投稿)」のように投稿者の総投稿数を添えてください。集計は 集計する の COUNT と GROUP BY です。投稿ごとに COUNT のクエリを 1 本ずつ発行しても動きますが、その形は Part 6 で「N+1 問題」と呼んで退治する対象です。JOIN と組み合わせて 1 本のクエリにできないか考えてみてください。
Part 6 へ
この Part では、速さを一度も測っていません。 Part 6 では、この「動くもの」を速くする側に回ります。 最初にやるのはコードを直すことではなく、どこが遅いかを測ることです(推測するな、計測せよ)。