NestJS 시작하기: 실전 입문 가이드
반응형
NestJS 시작하기: 실전 입문 가이드
목차
NestJS란?
NestJS는 Node.js의 효율적인 서버 애플리케이션 구축을 위한 프레임워크입니다. Angular에서 영감을 받아 TypeScript를 기본으로 사용하며, OOP(객체지향 프로그래밍), FP(함수형 프로그래밍), FRP(함수형 반응형 프로그래밍)의 요소들을 포함하고 있습니다.
주요 특징
- TypeScript 기반의 타입 안정성
- 의존성 주입을 통한 느슨한 결합
- 모듈화된 아키텍처
- Express/Fastify 호환성
- 풍부한 CLI 도구 지원
개발 환경 설정
필수 도구 설치
# Node.js 설치 (14.x 이상)
$ node --version
v16.x.x
# NestJS CLI 설치
$ npm i -g @nestjs/cli
# 프로젝트 생성
$ nest new my-nest-project
프로젝트 구조 설정
// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true
}
}
프로젝트 구조
src/
├── app.module.ts # 루트 모듈
├── main.ts # 애플리케이션 시작점
├── users/ # 사용자 관련 모듈
│ ├── dto/
│ │ ├── create-user.dto.ts
│ │ └── update-user.dto.ts
│ ├── entities/
│ │ └── user.entity.ts
│ ├── users.controller.ts
│ ├── users.service.ts
│ └── users.module.ts
└── common/ # 공통 기능
├── filters/
├── guards/
├── interceptors/
└── pipes/
핵심 개념 이해하기
1. 모듈 (Modules)
// users.module.ts
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService]
})
export class UsersModule {}
2. 컨트롤러 (Controllers)
// users.controller.ts
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
async findAll(): Promise<User[]> {
return this.usersService.findAll();
}
@Post()
async create(@Body() createUserDto: CreateUserDto): Promise<User> {
return this.usersService.create(createUserDto);
}
}
3. 서비스 (Services)
// users.service.ts
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private usersRepository: Repository<User>,
) {}
async findAll(): Promise<User[]> {
return this.usersRepository.find();
}
async create(createUserDto: CreateUserDto): Promise<User> {
const user = this.usersRepository.create(createUserDto);
return this.usersRepository.save(user);
}
}
실전 예제: REST API 만들기
DTO (Data Transfer Object) 정의
// create-user.dto.ts
export class CreateUserDto {
@IsString()
@IsNotEmpty()
readonly name: string;
@IsEmail()
readonly email: string;
@IsString()
@MinLength(6)
readonly password: string;
}
엔티티 정의
// user.entity.ts
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column({ unique: true })
email: string;
@Column()
password: string;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
}
데이터베이스 연결
// app.module.ts
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'postgres',
database: 'nestjs',
entities: [User],
synchronize: true,
}),
UsersModule,
],
})
export class AppModule {}
테스트 작성하기
단위 테스트
// users.service.spec.ts
describe('UsersService', () => {
let service: UsersService;
let repository: Repository<User>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UsersService,
{
provide: getRepositoryToken(User),
useValue: {
find: jest.fn(),
create: jest.fn(),
save: jest.fn(),
},
},
],
}).compile();
service = module.get<UsersService>(UsersService);
repository = module.get<Repository<User>>(getRepositoryToken(User));
});
it('should be defined', () => {
expect(service).toBeDefined();
});
describe('findAll', () => {
it('should return an array of users', async () => {
const users = [{ id: 1, name: 'Test User' }];
jest.spyOn(repository, 'find').mockResolvedValue(users);
expect(await service.findAll()).toBe(users);
});
});
});
실무 적용 팁
1. 환경 변수 관리
// config/configuration.ts
export default () => ({
port: parseInt(process.env.PORT, 10) || 3000,
database: {
host: process.env.DATABASE_HOST,
port: parseInt(process.env.DATABASE_PORT, 10) || 5432,
},
});
2. 예외 처리
// filters/http-exception.filter.ts
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();
response
.status(status)
.json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: exception.message,
});
}
}
3. 미들웨어 사용
// middleware/logger.middleware.ts
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: Function) {
console.log(`Request...`);
next();
}
}
4. API 문서화
// main.ts
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('API 문서')
.setDescription('NestJS API 설명')
.setVersion('1.0')
.addTag('users')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
await app.listen(3000);
}
마치며
NestJS는 엔터프라이즈급 애플리케이션 개발을 위한 강력한 프레임워크입니다. TypeScript의 타입 안정성과 모듈화된 아키텍처를 통해 확장 가능하고 유지보수하기 쉬운 애플리케이션을 구축할 수 있습니다.
추천 학습 자료
- NestJS 공식 문서
- TypeORM 문서
- TypeScript 핸드북
- Jest 테스팅 가이드
반응형
'JavaScript > NestJs' 카테고리의 다른 글
NestJS로 구현하는 게시판 API 실전 가이드 (0) | 2024.11.11 |
---|---|
NestJS CLI 인식 문제 해결하기: PATH 설정 가이드 (1) | 2024.11.10 |
댓글