第4章 NestJSでのデータベース接続とORMの使用

【NestJS入門シリーズ】第4章: NestJSでのデータベース接続とORMの使用

1. ORMとは

ORM(Object-Relational Mapping)は、オブジェクト指向プログラミングとリレーショナルデータベースの間のデータ変換を行う技術です。NestJSでは、ORMライブラリの一つであるTypeORMを使用して、データベースとのやり取りを簡単に行うことができます。

2. TypeORMのインストール

まず、TypeORMとその依存関係をプロジェクトにインストールします。以下のコマンドをターミナルで実行してください。

npm install @nestjs/typeorm typeorm mysql2

ここでは、MySQLを例にしていますが、他のデータベース(PostgreSQL、SQLiteなど)を使用する場合は、それに応じたドライバをインストールしてください。

3. データベース接続の設定

次に、TypeORMを使用してデータベースに接続するための設定を行います。src/app.module.tsを以下のように編集します。

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { User } from './user.entity';

@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'password',
database: 'test',
entities: [User],
synchronize: true,
}),
TypeOrmModule.forFeature([User]),
],
controllers: [AppController, UserController],
providers: [AppService, UserService],
})
export class AppModule {}

この設定では、MySQLデータベースに接続し、Userエンティティを使用するように指定しています。また、synchronize: trueを設定することで、エンティティの変更が自動的にデータベースに反映されるようになります。

4. エンティティの作成

次に、データベースのテーブルに対応するエンティティを作成します。src/user.entity.tsというファイルを新規作成します。

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

@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;

@Column()
name: string;

@Column()
age: number;
}

このエンティティでは、Userテーブルの構造を定義しています。@Entity()デコレーターは、このクラスがデータベースのテーブルに対応することを示します。

5. サービスの更新

次に、ユーザー管理のためのサービスを更新します。src/user.service.tsを以下のように編集します。

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';

@Injectable()
export class UserService {
constructor(
@InjectRepository(User)
private userRepository: Repository<User>,
) {}

create(user: { name: string; age: number }) {
const newUser = this.userRepository.create(user);
return this.userRepository.save(newUser);
}

findAll() {
return this.userRepository.find();
}

findOne(id: number) {
return this.userRepository.findOneBy({ id });
}
}

ここでは、TypeORMのリポジトリを使用して、ユーザーの作成、取得を行っています。@InjectRepository(User)デコレーターを使用して、Userエンティティに対応するリポジトリを注入しています。

6. コントローラーの更新

コントローラーも、サービスの変更に合わせて更新します。src/user.controller.tsを以下のように編集します。

import { Controller, Get, Post, Body, Param } from '@nestjs/common';
import { UserService } from './user.service';

@Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}

@Post()
create(@Body() user: { name: string; age: number }) {
return this.userService.create(user);
}

@Get()
findAll() {
return this.userService.findAll();
}

@Get(':id')
findOne(@Param('id') id: string) {
return this.userService.findOne(+id);
}
}

7. データベースのテスト

7.1 データベースのセットアップ

MySQLのデータベースを事前に作成する必要があります。以下のSQLを実行して、testデータベースを作成してください。

CREATE DATABASE test;

7.2 アプリケーションの起動

アプリケーションを再起動します。ターミナルで以下のコマンドを実行してください。

bashコードをコピーするnpm run start

7.3 Postmanでのテスト

Postmanを使用して、データベース操作が正しく機能するかを確認します。

  1. ユーザーの作成: POST /usersエンドポイントに対して以下のJSONデータを送信します。jsonコードをコピーする{ "name": "John Doe", "age": 30 }
  2. すべてのユーザーを取得: GET /usersエンドポイントにアクセスすると、作成したユーザーのリストが取得できます。
  3. 特定のユーザーを取得: GET /users/1エンドポイントにアクセスすると、IDが1のユーザーが取得できます。

8. データベース操作の詳細

8.1 CRUD操作の実装

TypeORMを使用すると、簡単にCRUD(Create, Read, Update, Delete)操作を実装できます。

8.1.1 ユーザーの更新

ユーザーを更新するためのメソッドをUserServiceに追加します。

update(id: number, user: { name?: string; age?: number }) {
return this.userRepository.update(id, user);
}

これをコントローラーに追加します。

@Patch(':id')
update(@Param('id') id: string, @Body() user: { name?: string; age?: number }) {
return this.userService.update(+id, user);
}
8.1.2 ユーザーの削除

ユーザーを削除するためのメソッドも追加します。

remove(id: number) {
return this.userRepository.delete(id);
}

コントローラーに以下を追加します。

@Delete(':id')
remove(@Param('id') id: string) {
return this.userService.remove(+id);
}

9. エラーハンドリング

エラーハンドリングは、APIを構築する上で非常に重要です。NestJSでは、HTTP例外を使用して、簡単にエラーハンドリングを実装できます。次のようにエラーハンドリングを追加できます。

import { NotFoundException } from '@nestjs/common';

findOne(id: number) {
const user = this.userRepository.findOneBy({ id });
if (!user) {
throw new NotFoundException(`User with id ${id} not found`);
}
return user;
}

このようにして、ユーザーが見つからない場合に404エラーを返すように設定できます。

10. まとめ

この章では、NestJSでのデータベース接続とORMの使用方法について詳しく解説しました。TypeORMを使用してデータベースのCRUD操作を実装し、エラーハンドリングについても学びました。