TypeScript + Express + Sequelize でAPI開発
概要
タイトルに記載した内容でタスク管理のAPIを作成する。
Passport も触るつもりでしたが無しに。
目標
- タスクの一覧が取得できること
- タスクの追加ができること
- タスクを完了・未完了状態にできること
- タスクの更新ができること
- タスクを削除できること
リポジトリ
プロジェクト作成
お決まりのコマンド。
適当に空ディレクトリを作成して実行。
yarn init -y
ライブラリのインストール
mysql と mysql2 があるが後者の方が良い?
Sequelize のドキュメントでも mysql2 が記載されているので mysql2 を使用する。
yarn add express passport sequelize helmet cors mysql2 body-parser
yarn add -D typescript ts-node sequelize-cli
yarn add -D @types/node @types/express @types/passport \
@types/sequelize @types/helmet @types/cors \
@types/validator @types/bluebird @types/body-parser
mysql2 の型定義は yarn から実行するとエラーが発生してインストール出来なかったので、下記を package.json に直接追記した。
Is it support typescript? · Issue #1157 · sidorares/node-mysql2 · GitHubを参照した。
{
...,
"devDependencies": {
...,
"@types/mysql2": "git+https://git@github.com/types/mysql2.git"
}
}
2020-12-27 追記
リクエストボディを取得するために body-parser
が必要だったので追記
Docker から API 実行
GitHub - GeekyAnts/express-typescript: Express + TypeScript + Boilerplate for Web / API App が参考になった。
今回は Express + MySQL の開発環境が作りたかったので少し変更。
nodemon を使うことで自動更新されて都度コマンドを実行する必要がなくなった。
nodemon についてはnodemon で Node.js サーバの再起動を自動化する | まくまく Node.js ノート を参考にした。
作成した Dockerfile と docker-compose.yml は以下のようになった。
FROM node:lts-alpine
RUN npm i -g nodemon typescript
EXPOSE 3000
WORKDIR /usr/src/app
version: '3.8'
services:
app:
build:
context: ./docker/app/
dockerfile: Dockerfile
volumes:
- .:/usr/src/app
ports:
- 3000:3000
command: ash -c "yarn run dev"
db:
image: mysql:8.0
volumes:
- db-store:/var/lib/mysql
- ./docker/db/init:/docker-entrypoint-initdb.d
- ./docker/log/mysql:/var/log/mysql
- ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
ports:
- 3306:3306
environment:
MYSQL_DATABASE: express
MYSQL_ROOT_PASSWORD: secret
TZ: Asia/Tokyo
volumes:
db-store:
sequelize-cli のディレクトリ設定
Sequelize を使用するので併せて sequelize-cli もインストールした。
.sequelizerc
というファイルを作成することでディレクトリパスなどの指定ができる。
ファイルの設定については The .sequelizerc file を参照した。
今回は下記の設定ファイルを作成した。
const path = require("path");
module.exports = {
config: path.resolve("src", "config", "database.json"),
"models-path": path.resolve("src", "db", "models"),
"seeders-path": path.resolve("src", "db", "seeders"),
"migrations-path": path.resolve("src", "db", "migrations"),
};
npx sequelize-cli init
を実行してディレクトリとファイルが生成される。
Model ファイルの作成
sequelize-cli を使って作成。
モデルファイルとマイグレーションファイルが一緒に作成される。
# name でモデル名を指定
# attributes でモデルが持つプロパティを指定
npx sequelize-cli model:generate --name Task --attributes userId:number,content:string
TypeScript に書き換え
作成されるファイルが JavaScript なので TypeScript に書き換えた。
import { Model, DataTypes, Sequelize } from 'sequelize'
export default class Task extends Model {
public id!: number
public user_id!: number
public content!: string
public completed!: boolean
public readonly created_at!: Date
public readonly updated_at!: Date
static initialize(sequelize: Sequelize) {
this.init({
user_id: DataTypes.NUMBER,
content: DataTypes.STRING,
completed: DataTypes.BOOLEAN,
}, {
sequelize,
modelName: 'Task',
tableName: 'tasks',
underscored: true,
createdAt: 'created_at',
updatedAt: 'updated_at',
})
return this
}
static associate() {}
}