getAllCat

controller

@ApiOperation({ summary: '모든 고양이 가져오기' })
@Get('all')
getAllCat() {
  return this.catsService.getAllCat();
}

service의 getAllCat 호출

service

async getAllCat() {
  const allCat = await this.catsRepository.findAll();
  const readOnlyCats = allCat.map((cat) => cat.readOnlyData);
  return readOnlyCats;
}

모든 cat을 DB에서 꺼내와서 반환해주는 로직

그러면 repository의

async findAll() {
  return await this.catModel.find();
}

find 해서 다 가져오는 게 다임. (필터 안걸면 다가져와짐)

댓글 기능 추가

nest g mo comments
nest g co comments
nest g s comments

controller.ts

import { Body, Controller, Get, Param, Post } from '@nestjs/common';
import { ApiOperation } from '@nestjs/swagger';
import { CommentsCreateDto } from '../dtos/comments.create.dto';
import { CommentsService } from '../services/comments.service';

@Controller('comments')
export class CommentsController {
  constructor(private readonly commentsService: CommentsService) { }

  @ApiOperation({
    summary: '모든 고양이 프로필에 적힌 댓글 가져오기'
  })
  @Get()
  async getAllComments() {
    return this.commentsService.getAllComments();
  }

  @ApiOperation({
    summary: '특정 고양이 프로필에 댓글 남기기'
  })
  @Post(':id')
  async createComments(@Param('id') id:string, @Body() body: CommentsCreateDto ) {
    return this.commentsService.createComments(id, body);
  }

  @ApiOperation({
    summary: '좋아요 수 올리기'
  })
  @Post(':id')
  async plusLike(@Param('id') id:string) {
    return this.commentsService.plusLike(id);
  }
}

controller 기능 summary 참조

이에 맞게 service를 만들어준다.

import { Injectable } from '@nestjs/common';
import { CommentsCreateDto } from '../dtos/comments.create.dto';

@Injectable()
export class CommentsService {
  async getAllComments() {
    return 'get all comments';
  }

  async createComments(id: string, comments: CommentsCreateDto) {
    console.log(comments);
    return 'hello world';
  }

  async plusLike(id: string) {
    
  }
}

이 때 사용하는 Dto 를 만들어준다

먼저 schema를 만들어준 후

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
import { Document, SchemaOptions, Types } from 'mongoose';
import { ApiProperty } from '@nestjs/swagger/dist/decorators';

const options: SchemaOptions = {
  timestamps: true,
};

@Schema(options)
export class Comments extends Document {
  @ApiProperty({
    description: '작성한 고양이 id',
    required: true,
  })
  @Prop({
    type: Types.ObjectId,
    required: true,
    ref: "cats"
  })
  @IsNotEmpty()
  author: Types.ObjectId;

  @ApiProperty({
    description: '댓글 컨텐츠',
    required: true,
  })
  @Prop({
    required: true,
  })
  @IsNotEmpty()
  @IsString()
  contents: string;

  @ApiProperty({
    description: '좋아요 수',
  })
  @Prop({
    default: 0,
  })
  likeCount: number;

  @ApiProperty({
    description: '작성된 (게시물,정보글)',
    required: true,
  })
  @Prop({
    type: Types.ObjectId,
    required: true,
    ref: "cats"
  })
  @IsNotEmpty()
  info: Types.ObjectId;
}

export const CommentsSchema = SchemaFactory.createForClass(Comments);

그 다음 dto를 만들어주기

import { PickType } from '@nestjs/swagger';
import { Comments } from '../comments.schema';

export class CommentsCreateDto extends PickType(Comments, [
  'author',
  'contents',
] as const) {}

그러면, 댓글, 좋아요에 관련된 기능들을 작업할 기반이 마련된다.

하나씩 바꿔가자

일단 Controller

import { Body, Controller, Get, Param, Patch, Post } from '@nestjs/common';
import { ApiOperation } from '@nestjs/swagger';
import { CommentsCreateDto } from '../dtos/comments.create.dto';
import { CommentsService } from '../services/comments.service';

@Controller('comments')
export class CommentsController {
  constructor(private readonly commentsService: CommentsService) {}

  @ApiOperation({
    summary: '모든 고양이 프로필에 적힌 댓글 가져오기',
  })
  @Get()
  async getAllComments() {
    return this.commentsService.getAllComments();
  }

  @ApiOperation({
    summary: '특정 고양이 프로필에 댓글 남기기',
  })
  @Post(':id')
  async createComments(
    @Param('id') id: string,
    @Body() body: CommentsCreateDto,
  ) {
    return this.commentsService.createComments(id, body);
  }

  @ApiOperation({
    summary: '좋아요 수 올리기',
  })
  @Patch(':id')
  async plusLike(@Param('id') id: string) {
    return this.commentsService.plusLike(id);
  }
}

맨 첫 줄

constructor(private readonly commentsService: CommentsService) {}

의존성 주입을 해준다…

Service.ts

import { BadRequestException, Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { CatsRepository } from 'src/cats/cats.repository';
import { Comments } from '../comments.schema';
import { CommentsCreateDto } from '../dtos/comments.create.dto';

@Injectable()
export class CommentsService {
  constructor(
    @InjectModel(Comments.name) private readonly commentsModel: Model<Comments>,
    private readonly catsRepository: CatsRepository,
  ) {}

  async getAllComments() {
    try {
      const comments = await this.commentsModel.find();
      return comments;
    } catch (error) {
      throw new BadRequestException(error.message);
    }
  }

  async createComments(id: string, commentData: CommentsCreateDto) {
    try {
      const targetCat = await this.catsRepository.findCatByIdWithoutPassword(
        id,
      );
      const { contents, author } = commentData;
      const vlaidateAuthor =
        await this.catsRepository.findCatByIdWithoutPassword(author);
      const newComment = new this.commentsModel({
        author: vlaidateAuthor._id,
        contents,
        info: targetCat._id,
      });
      return await newComment.save();
    } catch (error) {
      throw new BadRequestException(error.message);
    }
  }

  async plusLike(id: string) {
    try {
      const comment = await this.commentsModel.findById(id);
      comment.likeCount += 1;
      return await comment.save();
    } catch (error) {}
  }
}

Module

import 잘해줘야 함.

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CatsModule } from 'src/cats/cats.module';
import { Comments, CommentsSchema } from './comments.schema';
import { CommentsController } from './controllers/comments.controller';
import { CommentsService } from './services/comments.service';

@Module({
  imports: [
    MongooseModule.forFeature([
      { name: Comments.name, schema: CommentsSchema },
    ]),
    CatsModule,
  ],
  controllers: [CommentsController],
  providers: [CommentsService],
})
export class CommentsModule {}