NestJS에서 Stopwatch 모듈 구현하기

sh.j225·2023년 9월 4일
0
  1. Stopwatch 모듈 생성
    먼저, Stopwatch 모듈을 생성합니다. Nest CLI를 사용하거나 수동으로 모듈을 생성할 수 있습니다.
nest generate module stopwatch
  1. Stopwatch Entity 생성
    스톱워치 데이터를 저장하기 위한 Entity를 생성합니다. 이 Entity는 시작 시간, 종료 시간 및 대상 시간(초)을 포함합니다.
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm';
import { User } from './user.entity';

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

  @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
  startTime: Date;

  @Column({ type: 'timestamp', default: null, nullable: true })
  endTime: Date;

  @Column({ type: 'integer' })
  targetSeconds: number;

  @ManyToOne(() => User, (user) => user.stopwatches)
  user: User;
}
  1. Stopwatch Service 및 Controller 생성
    Stopwatch 서비스와 컨트롤러를 생성합니다. 서비스는 스톱워치 생성 및 종료를 처리하고, 컨트롤러는 API 엔드포인트를 노출합니다.

StopwatchService

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

@Injectable()
export class StopwatchService {
  constructor(
    @InjectRepository(Stopwatch)
    private stopwatchRepository: Repository<Stopwatch>,
  ) {}

  async createStopwatch(userId: number, targetSeconds: number): Promise<Stopwatch> {
    const stopwatch = new Stopwatch();
    stopwatch.user = { id: userId } as User;
    stopwatch.targetSeconds = targetSeconds;
    return await this.stopwatchRepository.save(stopwatch);
  }

  async endStopwatch(stopwatchId: number): Promise<Stopwatch> {
    const stopwatch = await this.stopwatchRepository.findOne(stopwatchId);
    if (!stopwatch) {
      throw new NotFoundException('Stopwatch not found');
    }

    stopwatch.endTime = new Date();
    return await this.stopwatchRepository.save(stopwatch);
  }
}

StopwatchController

import { Controller, Post, Param } from '@nestjs/common';
import { StopwatchService } from './stopwatch.service';

@Controller('stopwatches')
export class StopwatchController {
  constructor(private readonly stopwatchService: StopwatchService) {}

  @Post(':userId/start/:targetSeconds')
  async startStopwatch(
    @Param('userId') userId: number,
    @Param('targetSeconds') targetSeconds: number,
  ) {
    return this.stopwatchService.createStopwatch(userId, targetSeconds);
  }

  @Post(':stopwatchId/end')
  async endStopwatch(@Param('stopwatchId') stopwatchId: number) {
    return this.stopwatchService.endStopwatch(stopwatchId);
  }
}
  1. AppModule에 StopwatchModule 추가
    앞서 생성한 Stopwatch 모듈을 AppModule에 추가합니다. 이렇게 하면 StopwatchService와 관련된 의존성이 AppModule에서 해결됩니다.
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { StopwatchModule } from './stopwatch/stopwatch.module'; // Stopwatch 모듈 추가
// ...

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      useClass: TypeOrmConfigService,
      inject: [ConfigService],
    }),
    JwtModule.registerAsync({
      imports: [ConfigModule],
      useClass: JwtConfigService,
      inject: [ConfigService],
    }),
    MulterModule.register({
      // ...
    }),
    PostModule,
    ToDoModule,
    GroupModule,
    RoomModule,
    SeatModule,
    CardModule,
    UserModule,
    PaymentModule,
    ChatModule,
    StopwatchModule, // Stopwatch 모듈 추가
  ],
  controllers: [AppController, PaymentController, StopwatchController],
  providers: [
    AppService,
    S3Service,
    UploadService,
    PaymentService,
    PaymentGateway,
    MyLogger,
    Logger,
    StopwatchService,
  ],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware).forRoutes('*');
  }
}

오늘의 질의 응답😎

대용량 트래픽 발생 시 어떻게 대응해야 하나요?

나의 답변 😄
ORM을 사용할 때 복잡한 쿼리 처리에 대한 해결책은 다음과 같습니다. QueryBuilder로 가독성을 높이고, 필요한 경우 Raw SQL을 활용합니다. 데이터베이스 인덱스 최적화를 통해 쿼리 성능을 향상하고, 자주 사용되는 쿼리 결과를 캐싱하여 데이터베이스 부하를 줄입니다.

0개의 댓글