service -> module import-> app.ts
mongoose
npm
환경변수 - 디비정보 , port 노출 안되도록 .env
process.env.MONGODB_uri
process.env.port
USEcreate index -> index 설정
.env -> MODE = 'dev'
export class AppModule implements NestModule {
private readonly isDev : boolean = process.env.MODE ==='dev' ? true:false;
mongoose.set('debug',this.isDev) - //production 에서는 True -> log 남음
}
$ npm i --save class-validator class-transformer
app.useGlobalPipes(new ValidationPipe)
를 써줘야 등록됌!import {Prop, Schema, SchmaFactory} from '@nestjs/mongoose';
import {IsEmail, IsNoEmpty, IsString} from 'class-validator'
import {Document, SchemaOptions} from 'mongoose';
const options : SchemaOptions = {
timestamps: true;
}; // db에서 만들어질 때 업데이트, 만들어지는 날짜 찍어줌
@Schema(options)
export class Cat extends Document{ // 원래는 클래스
@Prop({
required: true,
unique : true,
}) //각 필드에 대한 constraint
@IsEmail() //validation
@IsNotEmpty() //validation
email: string; //column email
@Prop({
required: true,
})
@IsString()
@IsNotEmpty()
name: string; //column catname
@Prop({
required: true,
})
@IsString()
@IsNotEmpty()
password: string; //column password
@Prop({
required: false,
})
@IsString()
imgurl: string; //column imgurl
export const CatSchema = SchemaFactory.createForClass(Cat); // class -> schema
}
npm i bcrypt
. // npm i -D @types/bcrypt
DTO패턴
- Data Transfer Object - 데이터 교환을 위한 객체
- express router에 대응
-AOP 관점 지향 프로그래밍 반영
✓AOP : 부가기능을 aspect로 정의하여 핵심기능에서 부가기능을 분리함으로써 핵심기능을 설계할 때 객체지향을 지킬 수 있도록 도와주는 기법
// /cats/cats.controller.ts
@Post()
async signUp(@Body() body : CatRequestDto) {
console.log(body);
return await this.catsService.signUp(body)
}
// /cats/cats.request.dto
import {IsEmail, IsNoEmpty, IsString} from 'class-validator'
export class CatRequestDto {
@IsEmail()
@IsNotEmpty()
email:String;
@IsString()
@IsNotEmpty()
password:String;
@IsString()
@IsNotEmpty()
name:String;
}
// cats/catsService
@injectable()
export class CatsService {
constructor (@InjectModel (Cat.name) private readonly catModel: Model<cat>) {}
async signUp(body: CatRequestDto) {
const {email, name, password} = body;
const isCatExist = await this.catModel.exists({email});
if (isCatExist){
throw new UnauthorizedException ('해당하는 고양이는 이미 존재') //403안적어도 자동 반환
//throw new HttpException ('해당하는 고양이는 이미 존재합니다' 403)
}
const hashedPassword = await bcrypt.hash (password, 10);
const cat = await this.catModel.create({
email,
name,
password: hashedpassword,
})
return cats.readOnlyData;
}
}
```
```typescript
// cats/cats.schema.ts
readonly readOnlyData: {id: string; email:string; name:string}; //typing
CatSchema.virtual('readOnlyData').get(function(this.Cat){
return {
id : this.id,
email: this.email, // 보내줄 내용만 기록
name: this.name,
}
})
npm install --save @nestjs/swagger fastify-swagger
ApiOperation(summary)
추가 -> ex) post cats
회원가입@ApiProperty
로 표현Controller- @ApiResponse
- response에도 dto 사용 가능! - request와 동일하게 만들고 타입 지정Picktype
app.enableCors
추가// main.ts
async fucntion bootstrap() {
.....
const config = new DocumentBuilder() //각 요소 수정
.setTitle('Cats Informaiton Service')
.setDescription('The cats API description')
.setVersion('1.0.0')
.addTag('cats')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('docs', app, document);
app.enableCors({
origin : true,
credentials: true
}) //cors 추가!!
.....
}
// /cats/cats.controller.ts
@ApiResponse({ //실패한 경우 출력
status : 500,
description : 'server error....'
type : ReadOnlyDto // 응답값 dto
})
@ApiOperation({summary: '회원가입' }) // swagger페이지에 설명 추가가능
@Post()
async signUp(@Body() body : CatRequestDto) {
console.log(body);
return await this.catsService.signUp(body)
}
// /cats/cats.request.dto
import {IsEmail, IsNoEmpty, IsString} from 'class-validator'
export class CatRequestDto {
@ApiProperty({ // 데코레이터 추가-> swagger예시
example : "andsa@kakao.com",
description : 'email',
required: true
})
@IsEmail()
@IsNotEmpty()
email:String;
@ApiProperty({
example : "password123",
description : 'password',
required: true
})
@IsString()
@IsNotEmpty()
password:String;
@IsString()
@IsNotEmpty()
name:String;
}
// /cats/cats.request.dto - 상속으로 refactoring
import {IsEmail, IsNoEmpty, IsString} from 'class-validator'
import {Cat} from '../cats.schema';
export class CarRequestDto extends PickType (Cat, ['email','name'] as const{ //pickType -원하는 것만 가져오기
export class CatRequestDto {
@ApiProperty({ // 데코레이터 추가-> swagger예시
example : "320002",
description : 'id',
})
id: string;
}
}