Expressで簡易APIサーバー作成_1 Sequelizeでマイグレーションしてみる


概要

オリジナルアプリのフロントをReactで作成していて、APIサーバーをExpressで作成してみることにしました。バックでのJavaScriptの使われ方を知りたいと思っていたことがきっかけです。

公式によるとExpressとは、次の通りです。

Express は、Web アプリケーションとモバイル・アプリケーション向けの一連の堅固な機能を提供する最小限で柔軟な Node.js Web アプリケーション・フレームワークです。

ExpressでもRailsのActiveRecordのようにORMでDBを扱いたいと思っていたところ、Sequelizeというパッケージがあるようです。
使い方を調べてみました。

目的

ExpressのスケルトンからSequelizeを使ってCRUDの雛形をささっと作れるようなるために、手順をアウトプットすることが目的です。
今後、何回かに分けてアウトプットしていこうと思います。

今回の目標は次の通りです。

  • Expressアプリーケーションのスケルトンを作成する。
  • ユーザーを表すシンプルなモデルを作成する。
  • マイグレーションを実行してユーザーテーブルを作成する。

References

検証環境

  • MacOS Catalina 10.15.7
  • Node.js 14.5.0
  • mysql 5.6.47

Node.jsと使用するDBを用意しておいてください。
支障がなければNodeは最新版を入れておけば問題ないはず。
DBはSequelizeで使用できるDBを参照して使用するDB用意しておいてください。
DBの中身を確認するためのクライアントも用意してください。(Sequelなど)

作業フォルダやインストールオプション等は各自の環境に合わせ適当にご対応願います。

手順

  1. Expressアプリケーションスケルトン作成
  2. パッケージインストール
  3. Sequelize初期化とconfig確認
  4. データベース作成
  5. モデル・マイグレーションファイル作成
  6. マイグレーション実行

1.Expressアプリケーションスケルトン作成

ここではExpressアプリケーションスケルトンを作成します。
生成プログラム・ツール「express」を使用すると簡単に作成できます。
インストールしていない場合は、下記コマンドでインストールしましょう。

ターミナル
npm install express-generator -g

expressコマンドで現在のディレクトリにExpressアプリケーションスケルトンを作成します。
今回はAPIサーバーを作成するためviewはいらないので、--no-viewオプションをつけて作成します。
アプリ名はapiAppとしました。

ターミナル
express --no-view apiApp

コマンド実行後、以下のスケルトンが作成され、ターミナル上にログが出力されます。

【参考】作成されたスケルトンとログ

作成されたスケルトン

ログ

ログを見てみると、change directory:以下に3つのコマンドが表示されています。

ターミナル
cd apiApp
npm install
DEBUG=apiapp:* npm start

これらを順に実行すると、ローカルサーバーが立ち上がります。

ブラウザでlocalhost:3000にアクセスすれば、

という画面が表示されると思います。



2.パッケージインストール

これから作成していくAPIサーバーアプリで使用するパッケージをインストールしましょう。
アプリのルートディレクトリに移動してから、ターミナルで以下のコマンドを実行していきます。

  • Express本体 ( 1でインストールしたのは、スケルトン作成ツールのexpress-generator )
ターミナル
npm install express --save
  • Sequelize本体
ターミナル
npm install sequelize --save
  • Sequelize CLI ( 今後も使用することを考え、globalにインストールしました。)
ターミナル
sudo npm install -g sequelize-cli
  • DB用パッケージ ( 各自のDBに合わせてパッケージを変えてください。これはmysql用です。 )
ターミナル
npm install mysql2 --save

Sequelize CLI からSequelizeを使って、モデル・マイグレーションファイルの作成やマイグレーションなどをターミナルから実行できます。
Sequelize CLIのRead Me を参照ください。


3.Sequelize初期化とconfig確認

今回の目的は、Sequelizeを使用して、ユーザーを表すモデルを作成しマイグレーションすることです。
Sequelizeを使用するためには、まずSequelizeの初期化を行います。

まずはアプリのルートフォルダに移動しましょう。
Sequelize CLI を使ってSequelizeを初期化します。
ターミナルで、次のコマンドを実行してください。

ターミナル
npx sequelize init

アプリルートフォルダ内に、

  • config
  • migrations
  • models
  • seeders

というフォルダが作成されたことを確認してください。

【参考】フォルダ階層

モデル作成とマイグレーションを行う前に、configディレクトリ内のconfig.jsonを確認しましょう。
config.jsonにはDBへの接続情報を記述します。
各自の環境に合わせて記述してください。

デフォルトのconfig.json
config.json
{
  "development": {
    "username": "root",
    "password": null,
    "database": "database_development",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "test": {
    "username": "root",
    "password": null,
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "production": {
    "username": "root",
    "password": null,
    "database": "database_production",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}


実行環境の指定

config.jsonの3つのキー、development、test、production以下のオブジェクトで実行環境ごとの設定ができます。Sequelizeは環境変数NODE_ENVで指定された値をアプリルート/models/index.jsで読み込み実行します。
デフォルトはdevelopmentになります。

【参考】models/index.js

DBの指定

Sequelize CLIはデフォルトでmysqlがDBに設定されます。
他のDBを使用する場合は、dialectを編集してください。
Sequelizeで使用できるDB

ポートの指定

Sequelizeはデフォルトで、5432でDBを扱います。異なるポートを使用したい場合は、該当する環境にportフィールドを追加してください。


4.データベース作成

ここではSequelizeのdb:createを使用して、config.jsonに基づいたデータベースを作成します。
データベースを作成済の方は、このチャプターは飛ばしてください。

Sequelize CLI のdb:createによるデータベース作成

デフォルトのconfig.json(上で記載しているのでご参照ください)を使って、development環境でdb:createを実行し、データベース名:database_developmentというデータベースを作成します。


まず、環境変数NODE_ENVについて、環境変数一覧を表示して、以下を確認してください。
  • 環境変数NODE_ENVがdevelopmentに設定されている、もしくは環境変数にNODE_ENVが設定されていない
  • 環境変数NODE_ENVがdevelopment以外のものが設定されている場合は、developmentに設定する

環境変数一覧表示コマンド

ターミナル
export -p

次に、アプリのルートディレクトリに移動して、以下のコマンドを実行します。

ターミナル
npx sequelize db:create

database_developmentというデータベースが作成されたことをDBクライアントで確認してください。

【参考】db:create後のDBクライアント(Sequel)



5.モデル・マイグレーションファイル作成

では、いよいよユーザーを表すモデルを作成していきます。
ユーザーのモデルとして、氏名だけを持つシンプルなモデルを考えます。

モデル名とテーブル名をどうしようか考えていたところ、公式ドキュメントに以下の記述がありました。

A model in Sequelize has a name. This name does not have to be the same name of the table it represents in the database. Usually, models have singular names (such as User) while tables have pluralized names (such as Users), although this is fully configurable.

要約すると、
* モデル名とテーブル名は一致している必要はない。
* よく使われるのは、モデルは単数形、テーブル名は複数形というパターン。
* 例えばモデル名:User、テーブル名:とUsersとする。

例にならって、モデル名:Userとしてモデルを作成します。

まず、アプリのルートディレクトリに移動してください。

modelsディレクトリにはindex.jsのみ存在し、migrationsディレクトリは空であることを確認してください。(もちろん他のモデルを作成していた場合、それらのファイルが存在しています。)

そして、次のコマンドを実行します。
Userというモデル名でカラム名がnameというstring型のカラムを持つモデルファイルを生成します。

ターミナル
npx sequelize model:generate --name User --attributes name:string

modelsディレクトリとmigrationsディレクトリに、モデルファイルとマイグレーションファイルがそれぞれ作成されたことを確認してください。

【参考】model:create後のアプリフォルダ

Sequelizeでは、model:generateするとモデルファイルと共にマイグレーションファイルも生成されます。
モデルファイルやマイグレーションファイルの詳しい内容は次回以降追っていくことにして、少しだけ中身を見てみます。

モデルファイル

User.initの中で、モデル名とカラムについての記述があります。

user.js抜粋

  User.init({
    name: DataTypes.STRING
  }, {
    sequelize,
    modelName: 'User',
  });

マイグレーションファイル

Usersとテーブル名を自動で複数形にしてくれています。
id,createdAt,updatedAtはデフォルトで自動で付けてくれます。

マイグレーションファイル(○○-create-user.js)抜粋

    await queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      name: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });


6.マイグレーション実行

では、マイグレーションを実行してテーブルを作成しましょう。
アプリのルートディレクトリに移動して、次のコマンドを実行してください。

ターミナル
$ npx sequelize db:migrate

処理完了後、DBクライアントからテーブルが作成されたことを確認してください。

【参考】db:migrate後のDBクライアント(Sequel)


振り返りと次回の話題

今回の内容をざっとまとめると、以下を行いました。

  • Expressアプリケーションのスケルトン作成
  • Sequelize関連パッケージインストール
  • Sequelize-CLIで以下を実行
    • init でSequelizeを初期化し、configファイルを確認
    • db:create でデータベース作成
    • model:generate でUserモデルのモデル・マイグレーションファイル作成
    • db:migrate でマイグレーションを実行してUsersテーブル作成

次回は、ユーザーデータ取得処理、についてまとめる予定です。