【SvelteKit×NestJS】ゼロからアプリを作ってみよう!Part1〜データベース構築〜

Yuki Hamakawa
nextbeat-engineering
17 min readFeb 29, 2024
サムネイル画像 ”Let’s make an APP! Part1"

はじめに

こんにちは。2023年12月にネクストビートに入社して、保育士バンク!という保育士向け転職支援サービスを開発している浜川勇輝です!

保育士バンク!はフロントエンドにSvelteKit、APIにNestJSを採用しています。

前職では基本的にJavaしか経験のなかった僕は「Svelte?なんて読むの?」状態でした。

でも、ネクストビートは研修制度が充実しているので、一人で開発を進められるくらいにはキャッチアップできました(あとSvelteがシンプルで分かりやすい)。

せっかくSvelteKitとNestJSを学んだので、これらを使って簡単なデモアプリを作ってみようと思います。

「自分でWebアプリを作ってみたい!」という方、是非参考にしてみてください。

(自分自身、まだ勉強中なので記事を書いてアウトプットしながら勉強していきます!)

今回のゴール

作るのは簡単なToDoアプリです。ToDoの作成、表示、編集、削除というCRUD処理が一通りできるアプリを作ります。

プロジェクトの構成は以下の通りです。

  • フロントエンド:SvelteKit
  • バックエンド:NestJS
  • データベース:MySQL

これらのうち、今回はデータベースの構築のみを目指します。1つ1つ理解しながら進めていきましょう。

それでは作っていきましょう!

1. ツールのインストール

まずは各種ツールのインストールです。Macでの操作を前提とします。

1–1. Homebrewのインストール

Homebrewは主にmacOS上で動作するパッケージ管理ツールです。GitやNode.js、Pythonなど、様々なツールやアプリケーションを一元管理できます。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

1-2. nodenvのインストール

nodenvはNode.jsのバージョン管理ツールです。インストールできたら、nodenvを使ってNode.jsをインストールしましょう。

# nodenvのインストール
brew install nodenv

# ~/.bashrcに下記の1行を追記
eval "$(nodenv init -)"

# 設定の読み込み
source ~/.bash_profile

# Node.js20.10.0のインストール
nodenv install 20.10.0

1–3. pnpmのインストール

pnpmはNode.jsのパッケージ管理ツールです。npmと互換性を持ち、npmやyarnよりも高速なインストール、効率的かつ厳格なパッケージ管理を実現できます。

1–4. Dockerのインストール

データベースをコンテナで動かすためにDockerを使います。

2. リポジトリの作成(GitHub)

GitHubリポジトリを作成することで、プロジェクトの管理場所を作ります。

2–1. リモートリポジトリの作成

GitHubにログインして、リモートリポジトリを作成します。リポジトリ名は任意ですが、todo-app としておきます。

2–2. リモートリポジトリのクローン

作成できたら、ローカルにクローンします。

# リモートリポジトリのクローン
git clone <リモートリポジトリのリンク(HTTPSまたはSSH)>

3. データベースの作成(Docker)

Dockerを使ってMySQLのコンテナを作成し、データベースを構築しましょう。

3–1. docker-compose.ymlの作成

todo-appの直下にdocker-compose.yml を作成します。このファイルにコンテナの内容を定義し、コマンドを実行することで、設定内容に基づいたコンテナが作成されます。

todo-app
└──docker-compose.yml

docker-compose.yml には下記のようにMySQLコンテナ用の設定を記載します(今回はデモアプリなので、ユーザ名、パスワード等は全てtest としています)。

services:
mysql:
platform: linux/x86_64
image: mysql:8.0
environment:
MYSQL_USER: test
MYSQL_PASSWORD: test
MYSQL_ROOT_PASSWORD: test
MYSQL_DATABASE: test
ports:
- 3306:3306
volumes:
- ./mysql_data:/var/lib/mysql

3–2. コンテナの起動

下記コマンドでコンテナを起動します。

# コンテナの起動
docker-compose up -d

コンテナが立ち上がると、todo-app 直下にmysql_data というフォルダが作成されます。これはコンテナのデータを保持しておくための領域(ボリューム)です。

todo-app
├──mysql_data
└──docker-compose.yml

4. APIの作成(NestJS)

NestJSを使ってAPIを作成します。NestJSはNode.js上で動作するバックエンド開発のフレームワークです。

4–1. NestJSプロジェクトの作成

NestJSのプロジェクトはNest CLIを使えば簡単に構築できます。

まずはNest CLIをインストールして、todo-appの直下にtodo-api という名前でプロジェクトを作成しましょう。

# Nest CLIのインストール
pnpm i -g @nestjs/cli

# インストールの確認
nest -v

# NestJSプロジェクトの作成
# package managerはpnpmを選択
nest new todo-api
todo-app
├──mysql_data
├──todo-api
└──docker-compose.yml

4–2. リソースの作成

プロジェクトが作成できたら、ToDoのデータをやりとりするためのリソース(必要なファイル一式)を作成します。

# todosリソースの作成
# transport layerはREST APIを選択
cd todo-api
nest g resource todos

すると、下記のようにたくさんファイルが生成されます。

todo-app
└──todo-api
└──src
└──todos
├──todos.module.ts # モジュール:コンポーネントを1つにまとめる
├──todos.controller.ts # コントローラ:ルーティングを定義
├──todos.service.ts # サービス:ビジネスロジックを定義
├──todos.controller.spec.ts # コントローラのテストを定義
├──todos.service.spec.ts # サービスのテストを定義
├──dto
| ├──create-todo.dto.ts # DTO:作成時の受け渡しデータを定義
| └──update-todo.dto.ts # DTO:更新時の受け渡しデータを定義
└──entities
└──todo.entity.ts # エンティティ:データベースのテーブルを定義

5. データベースの接続・テーブルの作成(TypeORM

TypeORMを使ってAPIをデータベースに接続し、テーブルを作成します。

TypeORMはTypeScriptやJavaScriptで使えるO/Rマッパー(オブジェクト指向言語のオブジェクトと、RDBのデータを結びつけるソフトウェア)です。

5–1. TypeORMのインストール

下記コマンドでTypeORMをインストールします。

# TypeORMのインストール
pnpm install --save @nestjs/typeorm typeorm mysql2

5–2. エンティティの定義

ToDoデータのエンティティクラスを定義します。TypeORMはこれを元にデータベースのテーブルを作成します。

NestCLIで作成したtodo-api/src/todos/entities/todo.entity.ts に、テーブル定義を記載します。

import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Todo {
@PrimaryGeneratedColumn({ comment: 'タスクID' })
id: string;

@Column({ comment: 'タスク名' })
name: string;

@Column({ comment: 'タスク期限' })
deadline: Date;
}

Todoテーブルの項目は下記の3つとします。

  • id:タスクごとに振られる一意のID
  • name:タスクの名前
  • deadline:タスクの期限

5–3. DataSourceの作成

データベースの接続を定義するDataSourceファイルを作成します。

todo-api/src に下記の内容でdata-source.ts を作成します。

import { DataSource } from 'typeorm';
import { Todo } from './todos/entities/todo.entity';

export const AppDataSource = new DataSource({
type: 'mysql', // DBの種類
host: 'localhost', // ホスト名
port: 3306, // ポート番号
username: 'test', // docker-compose.ymlで指定したMYSQL_USER
password: 'test', // docker-compose.ymlで指定したMYSQL_PASSWORD
database: 'test', // docker-compose.ymlで指定したMYSQL_DATABASE
logging: true, // ログ出力有無
synchronize: false, // マイグレーション自動実行の有無
entities: [Todo], // エンティティクラス
migrations: ['dist/migration/*.js'], // マイグレーション実行対象ファイル
});
todo-app
└──todo-api
└──src
└──data-source.ts

5–4. DataSourceの読み込み

作成したDataSourceファイルを読み込むために、todo-api/src/app.module.ts を編集します。

import { AppDataSource } from './data-source';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TodosModule } from './todos/todos.module';

@Module({
imports: [TypeOrmModule.forRoot(AppDataSource.options), TodosModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

5–5. マイグレーションファイルの作成

エンティティを元にデータベースにテーブルを作成するための準備として、下記コマンドでマイグレーションファイルを作成します。

# src/data-source.tsを元にsrc/migration/TodosMigrationというマイグレーションファイルを作成
pnpm typeorm-ts-node-commonjs migration:generate src/migration/TodosMigration -d src/data-source.ts

成功すればtodo-api/src/migration に下記のようなマイグレーションファイルが作成されます。

// 作成されたマイグレーションファイル
import { MigrationInterface, QueryRunner } from 'typeorm';

export class TodosMigration1709105585276 implements MigrationInterface {
name = 'TodosMigration1709105585276';

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE
\`todo\` (\`id\` int NOT NULL AUTO_INCREMENT COMMENT 'タスクID',
\`name\` varchar(255) NOT NULL COMMENT 'タスク名',
\`deadline\` datetime NOT NULL COMMENT 'タスク期限',
PRIMARY KEY (\`id\`)) ENGINE=InnoDB`,
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE \`todo\``);
}
}
todo-app
└──todo-api
└──src
└──migration
└──1709105585276-TodosMigration.ts # ファイル名は固定ではない

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

マイグレーションを実行してデータベースにテーブルを作成します。

その前にビルドを実行して、todo-api/src/dist の中身を更新します。

# ビルドを実行
pnpm run build

ビルドが完了したら、いよいよマイグレーションを実行します。

# マイグレーションを実行
pnpm typeorm-ts-node-commonjs migration:run -d src/data-source.ts

6. 作成したテーブルの確認(Docker)

マイグレーションが成功し、テーブルが作成されていることを確認しましょう。

6–1. MySQLにログイン

MySQLにログインするために、まず、docker-compose.yml に記述したサービス名(ここではmysql)を指定し、コンテナ内でbashを起動します。

# コンテナ内でbashを起動
docker-compose exec mysql /bin/bash

bashが立ち上がったら、MySQLにログインします。パスワードの入力を求められるので、docker-compose.yml で指定したパスワード(ここではtest )を入力します。

# MySQLにログイン
mysql -u root -p

6–2. テーブルの確認

MySQLにログインできたら、テーブルの中身を確認しましょう。

# データベース一覧の表示
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.03 sec)

# データベースの選択
mysql> use test;

# テーブル一覧の表示
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| migrations |
| todo |
+----------------+
2 rows in set (0.01 sec)

# todoテーブルの確認
mysql> describe todo;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| deadline | datetime | NO | | NULL | |
+----------+--------------+------+-----+---------+----------------+
3 rows in set (0.02 sec)

以上でデータベースの構築は完了です。

次回はAPIを実装していきます!

We are hiring!

本記事をご覧いただき、ネクストビートの技術や組織についてもっと話を聞いてみたいと思われた方、カジュアルにお話しませんか?

・今後のキャリアについて悩んでいる
・記事だけでなく、より詳しい内容について知りたい
・実際に働いている人の声を聴いてみたい

など、まだ転職を決められていない方でも、ネクストビートに少しでもご興味をお持ちいただけましたら、ぜひカジュアルにお話しましょう!

🔽申し込みはこちら
https://hrmos.co/pages/nextbeat/jobs/1000008

また、ネクストビートについてはこちらもご覧ください。

🔽エントランスブック
https://note.nextbeat.co.jp/n/nd6f64ba9b8dc

--

--