4.4 KiB
4.4 KiB
description
| description |
|---|
| NestJS 백엔드 개발 규칙 |
이 파일은
.claude/commands/nestjs.md에 위치한다. 사용법:/nestjs [요청 내용]
아키텍처 원칙
관심사 분리 (Separation of Concerns)
Controller → HTTP 라우팅, 요청/응답 파싱만 담당
Service → 모든 비즈니스 로직 처리
Repository → 데이터 접근 계층 (TypeORM)
DTO → 요청/응답 데이터 형식 정의 및 검증
Controller에 비즈니스 로직 작성 금지new키워드로 수동 객체 생성 지양 → 의존성 주입(DI) 활용
모듈 구조
src/
├── modules/
│ └── user/
│ ├── user.module.ts
│ ├── user.controller.ts
│ ├── user.service.ts
│ ├── user.repository.ts ← 커스텀 Repository (선택)
│ └── dto/
│ ├── create-user.dto.ts
│ └── update-user.dto.ts
├── common/
│ ├── interceptors/ ← 응답 래핑, 에러 처리
│ ├── filters/ ← 전역 Exception Filter
│ ├── guards/ ← 인증/권한 Guard
│ ├── decorators/ ← 커스텀 데코레이터
│ └── pipes/ ← 전역 Validation Pipe
└── shared/
└── utils/ ← 순수 유틸 함수
DTO 작성 규칙
import { IsString, IsEmail, IsNotEmpty, MinLength } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
export class CreateUserDto {
@ApiProperty({ description: '사용자 이메일', example: 'user@example.com' })
@IsEmail({}, { message: '올바른 이메일 형식을 입력해 주세요.' })
@IsNotEmpty()
email: string;
@ApiProperty({ description: '비밀번호 (최소 8자)', example: 'password123' })
@IsString()
@MinLength(8, { message: '비밀번호는 최소 8자 이상이어야 합니다.' })
password: string;
}
- 모든 DTO는
class-validator+class-transformer사용 - 에러 메시지는 한국어로 작성
@ApiProperty()반드시 포함 (Swagger 명세용)
표준 응답 인터셉터
// common/interceptors/transform.interceptor.ts
@Injectable()
export class TransformInterceptor<T> implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handle().pipe(
map((data) => ({
success: true,
data: data ?? null,
})),
);
}
}
main.ts에서 전역 등록:app.useGlobalInterceptors(new TransformInterceptor())- 실패 응답(
success: false)은 아래 Exception Filter가 생성한다.
전역 Exception Filter
// common/filters/http-exception.filter.ts
@Catch()
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
// HTTP 상태 → 에러 코드 매핑 후 { success: false, error: { code, message } } 반환
// SYS_001 / AUTH_001 / VAL_001 등 CLAUDE.md 에러 맵 참조
}
}
Swagger 필수 적용
// main.ts
const config = new DocumentBuilder()
.setTitle('API 문서')
.setDescription('프로젝트 API 명세서')
.setVersion('1.0')
.addBearerAuth()
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api-docs', app, document);
- 모든 Controller에
@ApiTags()적용 - 모든 엔드포인트에
@ApiOperation(),@ApiResponse()작성 - 모든 DTO에
@ApiProperty()작성
인증 (JWT)
- Access Token: 만료 시간 짧게 (15분 ~ 1시간)
- Refresh Token: HttpOnly Secure 쿠키로 전달
@nestjs/jwt+@nestjs/passport사용- Guard를 통한 라우트 보호
성능 & 최신 트렌드 추가 규칙
- 캐싱: 자주 조회되는 데이터는
@nestjs/cache-manager(Redis) 활용 고려 - Rate Limiting:
@nestjs/throttler로 API 남용 방지 - Pagination: 목록 API는 반드시 커서 기반 또는 오프셋 페이지네이션 적용
- Logging:
winston또는@nestjs/common Logger사용,console.log지양 - Health Check:
@nestjs/terminus로/health엔드포인트 구성 권장 - Versioning: API 버전 관리 (
/v1/,/v2/) 적용 고려