前回の修正と準備

前回testというEntityを作ったけど、わかりにくくなるのでsampleに変更した。

モジュールの作成

npx nest g module sample

まず上記コマンドを使用し、モジュールを作る。なぜモジュール化するかを調べると散らかるので、また別の機会に。

公式ドキュメントに

対応するモジュール ディレクトリ内のドメインの近くに作成することをお勧めします。

と記載されているので、sample.entity.tsを作成したサンプルモジュール内に移行する。

必要なファイルを作成する

 npx nest g controller sample --no-spec
 npx nest g service sample --no-spec

controllerserviceを作成する。

controllerはルーティングを指定し、serviceは処理の記述を書くファイルという認識。

最後に、DBと疎通操作するためのRepositoryを作成する。なぜか作成するコマンドが用意されていないようなので、自作する。

cd src/sample
touch sample.repository.ts

各ファイルを作成する

sample.repository.ts

リポジトリはEntityManagerと同じですが、その操作は具象エンティティに限定されます。EntityManagerを介してリポジトリにアクセスすることができます。

上記を読んでもなんのことかわからない。

import { Injectable } from '@nestjs/common';
import { Sample } from 'src/sample/sample.entity';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';

@Injectable()
export class SampleRepository extends Repository<Sample> {
  constructor(@InjectRepository(Sample) repository: Repository<Sample>) {
    super(repository.target, repository.manager, repository.queryRunner);
  }
}

sample.controller.ts

これは先述した通り、ルーティングを指定するもの。

import { Controller, Delete, Get, Param, Patch, Post } from '@nestjs/common';
import { Sample } from './sample.entity';
import { SampleService } from './sample.service';

@Controller('sample')
export class SampleController {
  constructor(private readonly sService: SampleService) {}

  @Post()
  create() {
    return this.sService.createSample();
  }

  @Get()
  async findAll(): Promise<Sample[]> {
    return await this.sService.findAll();
  }

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

  @Patch(':id')
  update(@Param('id') id: string) {
    return this.sService.update(+id);
  }

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

sample.service.ts

これは先述した通り、処理を指定するもの。

import { Injectable, NotFoundException } from '@nestjs/common';
import { DeleteResult } from 'typeorm';
import { Sample } from './sample.entity';
import { SampleRepository } from './sample.repository';

@Injectable()
export class SampleService {
  constructor(private readonly sampleRepository: SampleRepository) {}

  // データ固定で新規作成
  public async createSample(): Promise<Sample> {
    return await this.sampleRepository.save({
      firstName: 'first',
      lastName: 'last',
      isActive: true,
    });
  }

  // 全件取得
  async findAll() {
    return await this.sampleRepository.find();
  }

  // id指定でデータ取得
  async findOne(id: number) {
    const sample = await this.sampleRepository.findOneBy({ id });
    if (!sample) {
      throw new NotFoundException(
        `${id}に一致するデータが見つかりませんでした。`,
      );
    }
    return sample;
  }

  // データ固定で更新
  async update(id: number): Promise<Sample> {
    const updated = await this.sampleRepository.update(id, {
      firstName: 'firstUpdate',
    });

    const updatedPost = await this.sampleRepository.findOneBy({ id });
    if (updatedPost) {
      return updatedPost;
    }

    throw new NotFoundException(
      `${id}に一致するデータが見つかりませんでした。`,
    );
  }

  // データ削除
  async remove(id: number): Promise<DeleteResult> {
    const response = await this.sampleRepository.delete(id);

    if (!response.affected) {
      throw new NotFoundException(
        `${id} に一致するデータが見つかりませんでした`,
      );
    }

    return response;
  }
}

sample.module.tsにまとめる

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { SampleController } from './sample.controller';
import { SampleRepository } from './sample.repository';
import { SampleService } from './sample.service';
import { Sample } from './sample.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Sample])],
  exports: [TypeOrmModule],
  controllers: [SampleController],
  providers: [SampleService, SampleRepository],
})
export class SampleModule {}

これで諸々処理は完了した。

C:Create

$ curl -X POST localhost:3000/sample
{"firstName":"first","lastName":"last","isActive":true,"id"
:2}

R:Read

全件取得

http://localhost:3000/sample/1

上記にアクセスすると、下記が取得できる。

[{"id":1,"firstName":"firstUpdate","lastName":"last","isActive":true},{"id":3,"firstName":"first","lastName":"last","isActive":true}]

Id指定で取得

http://localhost:3000/sample/1

上記にアクセスすると、下記が取得できる。

{"id":1,"firstName":"firstUpdate","lastName":"last","isActive":true}

U:Update

$ curl -X PATCH localhost:3000/sample/1
{"id":1,"firstName":"firstUpdate","lastName":"last","isActi
ve":true}

D:Delete

$ curl -X DELETE localhost:3000/sample/2
{"raw":[],"affected":1}

これでCRUD処理はできた。 ただ現状、すべてこちらで用意したデータを保存しているので、次はそこを触ってみる。