高瀬博道の技術ブログ

高瀬博道の技術ブログです。

NestJS でデータベース操作できるようにする - 5

前回

takasehiromichiex.com

サブスクライバ

TypeORM サブスクライバを使用すると、特定のエンティティイベントをリッスンすることができます。

まず、エンティティを作成します。

src/cats/cats.entity.ts
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";

@Entity()
export class Cat {
  @PrimaryGeneratedColumn()
  id: number;
  @Column()
  name: string;
  @Column()
  age: number;
  @Column()
  breed: string;
}

次に、サブスクライバを作成します。

src/cats/cats.subscriber.ts
import {
  DataSource,
  EntitySubscriberInterface,
  EventSubscriber,
  InsertEvent,
} from "typeorm";
import { Cat } from "./cats.entity";

@EventSubscriber()
export class CatsSubscriber implements EntitySubscriberInterface<Cat> {
  constructor(dataSource: DataSource) {
    dataSource.subscribers.push(this);
  }

  listenTo() {
    return Cat;
  }

  beforeInsert(event: InsertEvent<Cat>) {
    console.log("Before Insert:", event.entity);
  }
}

次に、モジュールに紐づけます。

src/cats/cats.module.ts
import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { CatsController } from "./cats.controller";
import { Cat } from "./cats.entity";
import { CatsService } from "./cats.service";
import { CatsSubscriber } from "./cats.subscriber";

@Module({
  imports: [TypeOrmModule.forFeature([Cat])],
  controllers: [CatsController],
  providers: [CatsSubscriber, CatsService],
})
export class CatsModule {}

CatsSubscriberを追加しています。

コントローラも変更します。

src/cats/cats.controller.ts
import { Body, Controller, Get, Post, UseInterceptors } from "@nestjs/common";
import { CreateCatDto } from "src/dto/cat/cat.dto";
import { CatsService } from "./cats.service";
import { ValidationPipe } from "../pipe/validation/validation.pipe";
import { User } from "src/decorator/user/user.decorator";
import { Cat } from "./cats.entity";

@Controller("cats")
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Post()
  create(@Body(new ValidationPipe()) createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }
  @Get()
  async findAll(): Promise<Cat[]> {
    return await this.catsService.findAll();
  }

  @Get("abc")
  async findOne(@User() user: any): Promise<void> {
    console.log(user);
  }
}

サービスも変更します。

src/cats/cats.service.ts
import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { Cat } from "./cats.entity";

@Injectable()
export class CatsService {
  constructor(@InjectRepository(Cat) private userRepository: Repository<Cat>) {}

  create(cat: Cat) {
    console.log("prod");
    this.userRepository.save(cat);
  }
  async findAll(): Promise<Cat[]> {
    console.log("prod");
    return await this.userRepository.find();
  }
}

userRepositoryを使用するように、全体的に修正しています。

便宜上、dtoも修正しています。

src/dto/cat/cat.dto.ts
import { IsInt, IsString } from "class-validator";

export class CreateCatDto {
  id: number;
  @IsString()
  name: string;
  @IsInt()
  age: number;
  @IsString()
  breed: string;
}

これで、POST localhost:3000/catsを呼び出すと、Before Insert: { name: 'meow', age: 8, breed: 'djmaro' }などと表示されるようになりました。

まとめ

ここまでで、

  • サブスクライバについて

を学びました。

次回も、データベース操作を掘り下げようと思います。

コード

今回のコードは、以下に格納しました。

github.com

takasehiromichiex.com