API 구현하기 전에 기본적으로 뭘 셋팅해줘야 하나 이것저것 찾아보다가 일단 제일 많이 나온? 부분만 기본적으로 설정해보기..
main.ts
에서 설정 가능!
const app = await NestFactory.create(AppModule, { cors: true }); // 방법 1
app.enableCors(); // 방법 2
➡️ 위 방법대로 설정 시, default 옵션은 다음과 같음
{
"origin": "*",
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"preflightContinue": false,
"optionsSuccessStatus": 204
}
app.enableCors()
내에 지정할 옵션 명시app.enalbeCors({
origin: ['url1', 'url2', ...], // 허용할 도메인 (단일 도메인일 경우 [] 생략)
methods: 'GET, PUT, ...', // 허용 메서드
credentials: true, // 인증 정보 포함 여부
...
})
config, cross-env 모듈을 사용하여 개발 환경(개발, 배포)에 따른 환경 변수 설정하기
config
, cross-env
모듈 설치npm i @nestjs/config cross-env
package.json
설정 추가 : 실행 환경에 따른 NODE_ENV
지정 → dev=development, prod=production
"scripts": {
"start:dev": "npm run prebuild && cross-env NODE_ENV=development nest start --watch",
"start:prod": "cross-env NODE_ENV=production node dist/main",
"prebuild": "rimraf dist"
},
...
app.module.ts
: 실행 환경에 따른 env
파일 지정 → start:prod
실행 시 package.json
설정에 의해 NODE_ENV=production
이므로 .prod.env
를 실행하고, 그 외의 경우(start:dev
) .dev.env
실행import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule } from '@nestjs/config';
import * as process from 'process';
import { Member } from './member/Member.entity';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [],
cache: true,
envFilePath: process.env.NODE_ENV === 'production' ? '.prod.env' : '.dev.env'
})
],
...
})
TypeORM
: TypeScript와 JavaScript를 사용한 객체 관계 매핑 수행 (Java의 JPA와 같은 역할!)
$ npm install @nestjs/typeorm typeorm mysql2
.env
: DB 설정 → 보안에 민감한 정보이므로 .gitignore
에 추가DB_HOST=host 주소
DB_PORT=포트번호
DB_USERNAME=사용자명
DB_PASSWORD=비밀번호
DB_DATABASE=사용할 스키마명
app.module.ts
: env
의 DB 설정을 가져와서 실행@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: process.env.DB_HOST,
port: +process.env.DB_PORT, // + : 문자열 → 숫자 변환
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
entities: [사용할 엔티티 목록],
synchronize: true // 실행 시 entites 내의 엔티티에 해당하는 테이블 자동 생성
})
],
...
})
엔티티를 생성하여 애플리케이션과 DB가 잘 연결되었는지 확인해보기!
src/member/Member.entity.ts
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity() // 엔티티 지정 : () 안붙이면 실행 시 에러 발생
export class Member {
@PrimaryGeneratedColumn() // PK : AI 적용
id: number;
@Column({type: 'varchar', nullable: false, length: 20}) // 컬럼 제약조건 지정 가능
name: string;
}
app.modules.ts.
: entities
에 생성한 엔티티 추가import { Member } from './member/Member.entity';
@Module({
imports: [
TypeOrmModule.forRoot({
entities: [Member],
...
})
],
...
})
: 애플리케이션 실행 시 env
에 지정한 스키마에 테이블이 생성되고, 각 컬럼마다 제약조건이 잘 설정된 것을 확인할 수 있다!
swagger
모듈 설치npm i --save @nestjs/swagger swagger-ui-express
main.ts
: swagger 문서를 사용하기 위한 기본 설정 추가await app.listen(3000)
를 실행하면 애플리케이션이 요청을 수신하기 시작함. 이때, listen()
이 호출된 후에 swagger 모듈 설정이 실행되면 해당 모듈이 API 엔드포인트르 찾지 못해 404 에러가 발생하므로, 모든 모듈의 설정 및 생성을 끝낸 후에 listnen()
을 가장 마지막에 실행해줘야 함!import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule, { cors: true });
// 기본 설정
const config = new DocumentBuilder()
.setTitle('API 문서')
.setDescription('API 문서입니다.')
.setVersion('1.0')
.build();
// 문서 생성
const document = SwaggerModule.createDocument(app, config);
// localhost:3000/api 접속 시 생성한 swagger 문서 실행
SwaggerModule.setup('api', app, document);
await app.listen(3000);
}
bootstrap();
@ApiTags()
: 컨트롤러에 대한 태그@ApiOperation()
: 메서드에 대한 설명@ApiResponse()
: 상태에 따른 응답 반환 형태@ApiBody()
: 요청 Body에 대한 정보@ApiParam()
: 요청 파라미터에 대한 정보@ApiQuery()
: 쿼리에 대한 정보@ApiProperty()
: 프로퍼티에 대한 정보 (DTO에서 주로 사용)
app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
@ApiTags('기본 API')
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
@ApiOperation({ summary: '홈', description: '홈 접속' })
@ApiResponse({ status: 200, description: '성공'})
@ApiResponse({status: 404, description: '실패'})
getHello(): string {
return this.appService.getHello();
}
}