🔩 ねじき教室 Go と Web の教室

何をどう作るか

読了目安 約3分

掲示板「ねじ板」の要件、URL 設計、テーブル設計を先に決めて、プロジェクトの土台を用意します。

この章の目次

この Part では、小さな掲示板サービス「ねじ板」を一つ作り切ります。

この章でやることは次の 3 つです。

  • 要件を言葉で決めて、URL 設計に落とす
  • テーブルを設計して、CREATE TABLE まで済ませる
  • Go プロジェクトを初期化して、依存パッケージを取得する

作るもの

ねじ板の要件は 2 つだけです。

  • 誰でも、投稿の一覧を見られる
  • ユーザー登録してログインした人だけ、投稿できる

主役は 2 つ目の「ログインした人だけ」です。 これには、ユーザーの保存、パスワードの安全な扱い、ログイン状態の維持が必要です。

URL 設計

ねじ板の URL は 7 つです。

メソッドパス役割
GET/投稿の一覧を表示する
GET/registerユーザー登録フォームを表示する
POST/registerユーザーを登録する
GET/loginログインフォームを表示する
POST/loginログインする
POST/logoutログアウトする
POST/posts投稿を保存する

メソッドの使い分けは HTTP を生で読む のとおり、見るだけの操作は GET、データを変える操作は POST です。 ログインしていないと使えないのは POST /posts だけです。

テーブル設計

テーブルは「ユーザー」と「投稿」の 2 つです。

users テーブル:

入るもの
idBIGINT自動採番の番号(主キー)
nameVARCHAR(50)ユーザー名。重複を禁止する
password_hashVARCHAR(255)パスワードのハッシュ値
created_atDATETIME登録日時

posts テーブル:

入るもの
idBIGINT自動採番の番号(主キー)
user_idBIGINT投稿したユーザーの users.id
bodyTEXT投稿の本文
created_atDATETIME投稿日時

posts に持たせるのは投稿者の名前ではなく user_id で、一覧を出すときは 複数のテーブルと JOIN のとおり JOIN で名前を引きます。 名前を投稿ごとにコピーすると、ユーザー名の変更時に全投稿を書き換える羽目になるからです。

password_hash にパスワードをそのまま保存しない理由は 3 章で説明します。

CREATE TABLE 文は次のとおりです。

SQL
CREATE DATABASE neziki_board;
USE neziki_board;

CREATE TABLE users (
    id            BIGINT AUTO_INCREMENT PRIMARY KEY,
    name          VARCHAR(50)  NOT NULL UNIQUE,
    password_hash VARCHAR(255) NOT NULL,
    created_at    DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE posts (
    id         BIGINT AUTO_INCREMENT PRIMARY KEY,
    user_id    BIGINT   NOT NULL,
    body       TEXT     NOT NULL,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);

name 列の UNIQUE が「重複を禁止する」の実体で、同じ名前の 2 人目の INSERT はエラーで拒否されます(3 章でこのエラーを使います)。 DEFAULT CURRENT_TIMESTAMP は、INSERT で値を省略したときに現在時刻が自動で入る指定です。

URL とテーブルを先に決める理由

URL の表とテーブル定義が決まると、残りの仕事は「URL ごとにハンドラを書き、テーブルを読み書きする」ことに分解されます。 2 章から 5 章で、この 7 つの URL を順に埋めていきます。

プロジェクトの準備

シェル
mkdir neziki-board
cd neziki-board
go mod init neziki-board
go get github.com/go-sql-driver/mysql golang.org/x/crypto/bcrypt
mkdir templates

依存は 2 つだけです。

  • go-sql-driver/mysql:database/sql から MySQL に接続するためのドライバです。Go から SQL を使う で使ったものと同じです。
  • golang.org/x/crypto/bcrypt:パスワードのハッシュ化に使います(3 章)。

ディレクトリ構成は最後までこの形です。

テキスト
neziki-board/
├── go.mod
├── go.sum
├── main.go        ← 2 章から書き始める
└── templates/     ← 画面の HTML テンプレートを置く

データベースの準備と動作確認

MySQL は Part 4 で作った Docker のコンテナと接続情報(root ユーザー、パスワード neziki、ポート 3306)をそのまま使います。 止めていた場合は docker start で起動してから、mysql クライアントに入ってください。

シェル
docker exec -it コンテナ名 mysql -uroot -pneziki

コンテナ名は Part 4 で付けた名前に読み替えてください。 接続できたら、CREATE TABLE 文を流し込み、テーブルを確認します。

SQL
SHOW TABLES;
テキスト
+------------------------+
| Tables_in_neziki_board |
+------------------------+
| posts                  |
| users                  |
+------------------------+
2 rows in set (0.00 sec)

posts と users の 2 つが表示されれば、この章は完了です。