TypeORMとPostgreSQLを使ったNest.js CRUD REST APIの構築方法

他のNode.jsフレームワークと同様に、Nest.jsは堅牢でスケーラブルなバックエンドサービスを構築するための包括的なツールキットを提供します。それにもかかわらず、Nest.jsで作成、読み取り、更新、削除(CRUD)操作を効率的に実装する方法を理解することが重要です。これらはAPIの開発における最も基本的な操作です。

TypeORMとPostgreSQLデータベースを使用してNest.js CRUD REST APIを構築する方法を学びます。

Nest.jsの始め方

はじめに、Nest.jsコマンドラインツールをインストールします:

npm i -g @nestjs/cli

次に、次を実行して新しいプロジェクトを作成します:

nest new crud-app

CLIツールはパッケージマネージャを選択するように求めます。最も好ましいと思うオプションを選択します。Nodeパッケージマネージャであるnpmを使用します。

CLIは、アプリケーションを実行するために必要なすべての必要な設定ファイルと初期の依存関係を備えた基本的なNest.jsプロジェクトを足場にします。

最後に、プロジェクトディレクトリに移動して開発サーバーを起動します。

cd crud-app
npm run start

このプロジェクトのコードはGitHubリポジトリにあります。

PostgreSQLデータベースの作成

このチュートリアルではクラウドPostgreSQLインスタンスを使用しますが、代わりにローカルPostgreSQLデータベースを設定することもできます。PostgreSQLはWindows、macOS、またはLinuxにインストールできます。

クラウドPostgreSQLインスタンスを設定するには:

  1. ElephantSQLにアクセスしてサインアップし、アカウントの概要ページにログインします。
  2. ページの左上にある新しいインスタンスの作成ボタンをクリックして、アプリケーションの新しいインスタンスを作成します。
  3. インスタンスの名前を入力し、無料プランを選択し、最後に地域を選択してセットアッププロセスを完了します。
  4. データベースインスタンスを作成したら、設定ページに移動し、提供されているデータベースURLをコピーします。

データベース接続の設定

プロジェクトのルートディレクトリで、.envファイルを作成し、データベース接続URLを次のように貼り付けます:

DATABASE_URL="<your connection url here>"

次に、これらのパッケージをインストールします:

npm install pg typeorm @nestjs/typeorm @nestjs/config

次に、CLIツールを使用してデータベースモジュールを作成します。

nest g module database

database/database.module.tsファイルを開き、次のデータベース設定コードを追加します:

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from '../users/models/user.entity';
@Module({
imports: [
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => ({
type: 'postgres',
url: configService.get('DATABASE_URL'),
entities: [User],
synchronize: true
}),
}),
],
})
export class DatabaseModule {}

このデータベースモジュールは、必要な接続パラメータであるデータベースURLを使用してTypeORMモジュールを構成することで接続を処理します。

さらに、PostgreSQLデータベーステーブルに格納されたデータの構造とプロパティを指定する構成の一部としてUserエンティティを定義します。

この段階では、まだユーザーエンティティを作成していないため、コードはエラーをスローする可能性があります。次の手順でそれを行います。

app.module.tsファイルの更新

最後に、メインアプリケーションモジュールを更新して、データベースモジュールの設定を含めます。

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { DatabaseModule } from './database/database.module';
@Module({
imports: [
ConfigModule.forRoot({
envFilePath: '.env',
}),
DatabaseModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

ユーザーモジュールの定義

ユーザーモジュールは、APIのCRUD機能を実装するために必要なロジックをカプセル化および管理する責任を負う、集中型コンポーネントとして機能します。

このターミナルコマンドを実行して、APIのユーザーモジュールを作成します。

nest g module users

CLIツールは、ユーザーモジュールを作成するだけでなく、行われた変更を反映するようにapp.module.tsファイルを自動的に更新します。これは、新しく作成されたモジュールであるユーザーがアプリケーションのモジュール構成に適切に統合されることを保証します。

ユーザーエンティティの作成

TypeORMは、JavaScriptオブジェクトをデータベーステーブルにマッピングすることで、TypeScriptを使用するアプリケーションにおけるデータベースの相互作用を簡素化するオブジェクトリレーショナルマッピング(ORM)ライブラリです。

TypeORMを使用してユーザーエンティティを作成することで、PostgreSQLデータベースのユーザーデータの構造とプロパティを定義します。

ユーザーディレクトリで、新しいmodels/user.entity.tsを作成し、次のコードを追加します。

import { Entity, PrimaryGeneratedColumn, Column, } from "typeorm";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
}

ユーザーエンティティは、データベースに格納されたユーザーデータの構造を定義します。この場合、それは主キー列としてのID、および名前メール列とその対応するプロパティです。

CRUD APIサービスの作成

次に、以下のコマンドを実行してCRUD操作のロジックを管理するAPIサービスを作成します:

nest g service users

user-auth.service.tsファイルを開き、次のコードを追加します:

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import {User} from './models/user.entity';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private userRepository: Repository<User>,
) {}
async findAll(): Promise<User[]> {
return this.userRepository.find();
}
async findOne(id: number): Promise<User> {
return this.userRepository.findOne({ where: { id } });
}
async create(user: Partial<User>): Promise<User> {
const newuser = this.userRepository.create(user);
return this.userRepository.save(newuser);
}
async update(id: number, user: Partial<User>): Promise<User> {
await this.userRepository.update(id, user);
return this.userRepository.findOne({ where: { id } });
}
async delete(id: number): Promise<void> {
await this.userRepository.delete(id);
}
}

このUsersServiceクラスは、CRUD操作を処理することに特化したさまざまなAPIメソッドを定義します。これらのメソッドには、すべてのユーザーのデータの取得、ID番号を使用して特定のユーザーの検索、新しいユーザーの作成、既存のユーザーの更新、およびデータベース内の特定のユーザーのデータを削除するためのメソッドが含まれます。

APIのコントローラの定義

ユーザー関連の操作のためのAPIエンドポイントを管理するコントローラを作成します。

nest g controller users

次に、次のコードをusers.controller.tsファイルに追加します。

import { Controller, Get, Post, Body, Put, Param, Delete, NotFoundException, HttpCode } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from './models/user.entity';
@Controller('api/users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
async findAll(): Promise<User[]> {
return this.usersService.findAll();
}
@Post()
@HttpCode(201)
async create(@Body() user: User): Promise<User> {
const createdUser = await this.usersService.create(user);
return createdUser;
}
@Put(':id')
async update (@Param('id') id: number, @Body() user: User): Promise<any> {
await this.usersService.update(id, user);
return { message: 'User updated successfully' };
}
@Delete(':id')
async delete(@Param('id') id: number): Promise<any> {
const user = await this.usersService.findOne(id);
if (!user) {
throw new NotFoundException('User does not exist!');
}
await this.usersService.delete(id);
return { message: 'User deleted successfully' };
}
}

コントローラは、ユーザー操作のためのAPIエンドポイントを管理します。すべてのユーザーを取得するためのGETリクエスト、新しいユーザーを作成するためのPOSTリクエスト、既存のユーザーを更新するためのPUTリクエスト、ユーザーを削除するためのDELETEリクエストを処理します。

UsersServiceを利用し、Userエンティティと対話することにより、このコントローラはデータベースに格納されたデータに関するユーザー関連の操作を管理するための完全なAPIを提供します。

users.module.tsファイルの更新

最後に、Userエンティティとデータベースへの接続を確立するTypeORMモジュールを組み込むように、users.module.tsファイルを以下のように更新します。

import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './models/user.entity';
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService]
})
export class UsersModule {}

最後に、開発サーバーを起動してPostmanを使用してCRUD操作をテストします。

npm run start

サーバーはポート3000で起動し、http://localhost:3000/api/usersでAPIリクエストを送信できます。

Nest.jsでバックエンドアプリケーションを構築する

シンプルなREST APIを開発している場合でも、複雑なWebアプリを開発している場合でも、Nest.jsは信頼性が高く、堅牢なバックエンドシステムを構築するための包括的な機能と機能を提供します。

Nest.jsは、Express.jsよりもプロジェクト開発に対するより構造化されたアプローチを提供します。これにより、整理されたモジュール式の設計パターンのおかげで、複雑なアプリケーションを確実に構築、拡張、および維持できます。