3. Backend/NestJS / / 2024. 3. 12. 16:29

[코드팩토리 NestJS 강의] Query and Parameters (쿼리와 파라미터)

1. REST API 세트(GET, POST, PUT, DELETE)

Method 주소 의미 사용
[GET] http://localhost:3000/posts  다수의 Post를 가져온다 Query 사용
[GET] http://localhost:3000/posts/11 11이라는 ID를 갖고있는 Post하나를 가져온다. Query 사용
[POST] http://localhost:3000/posts 새로운 Post를 생성한다 Body 사용
[PATCH] http://localhost:3000/posts/8 8이라는 ID를 갖고있는 Post를 부분 변경한다. Body 사용
[PUT] http://localhost:3000/posts/8 8이라는 ID를 갖고있는 Post를 변경하거나 생성한다 Body 사용
[DELETE] http://localhost:3000/posts/3 3이라는 ID를 갖고있는 Post를 삭제한다 Body 사용
  • PATCH : 업데이트 역할
  • PATCH와 PUT의 차이점은
    • PATCH의 경우, 변경하고 싶은 값만 Body에 넣어서 보내주면 존재하는 posts에 대해서 해당하는 아이디값을 갖고있는 post에 값들을 변경해준다
    • PUT의 경우, 해당하는 아이디에 대한 모든 정보를 다 넣어줘야 한다 (* 여차하면 생성해야하기에)
    • PATCH같은 경우는 변경하고 싶은 값만 넣어주면 되지만 PUT같은 경우는 post를 생성할때 필요한 모든 데이터를 같이 넣어줘야지만 변경하거나 생성하게 됨
      • 해당하는 ID가 있을 경우는 변경하지만, 존재하지 않는다면 생성을 한다
  • GET요청 : pagination같은 것을 하게되면 GET요청에서 끝에 query달아서 필터링하는 방법도 있음

 

2. 구현하기

/* eslint-disable prettier/prettier */
import {
  Body,
  Controller,
  Delete,
  Get,
  NotFoundException,
  Param,
  Post,
  Put,
} from '@nestjs/common';
import { PostsService } from './posts.service';

/**
 * id : number
 * authour : string
 * title : string
 * content : string
 * likeCount : number
 * commentCount : number
 */

interface PostModel {
  id: number;
  author: string;
  title: string;
  content: string;
  likeCount: number;
  commentCount: number;
}

// let으로 설정한 이유 : 데이터를 추가,삭제,변경 할것이기 때문
let posts: PostModel[] = [
  {
    id: 1,
    author: 'newjeans_official',
    title: '뉴진스 민지',
    content: '메이크업 고치고 있는 민지',
    likeCount: 1000000,
    commentCount: 99999,
  },
  {
    id: 2,
    author: 'newjeans_official',
    title: '뉴진스 해린',
    content: '노래연습하고있는 해린',
    likeCount: 1000000,
    commentCount: 99999,
  },
  {
    id: 3,
    author: 'blackpink_official',
    title: '블랙핑크 로제',
    content: '종합운동장에서 공연중인 로제',
    likeCount: 1000000,
    commentCount: 99999,
  },
];
@Controller('posts')
export class PostsController {
  constructor(private readonly postsService: PostsService) {}

  // 1) GET /posts
  //    모든 post를 다 가져온다
  @Get()
  getPosts() {
    return posts;
  }
  // 2) GET /posts/:id
  //    id에 해당되는 post를 가져온다 => path parameter를 만들어야 함!!
  //    예를들어서 id=1일 경우 id가 1인 포스트를 가져온다
  @Get(':id')
  // :은 Param 이라는 뜻이라 id만 정의해주면 됨
  getPost(@Param('id') id: string) {
    const post = posts.find((post) => {
      post.id === +id;
    });

    // post가 없을때, Not Found Exception 던지기 (404 Not Found 에러)
    // 에러 반환하는 이유 : 아무것도 없는 값을 반환해주는것이아닌 문제가 있다는 실질적인 메세지를 전달하기 위함
    if (!post) {
      throw new NotFoundException();
    }
    return post; // (200 OK)
  }

  // 3) POST /posts
  //    POST를 생성한다
  @Post()
  postPost(
    @Body('author') author: string, // 데이터를 body에서 받을건데, body안에 author라는 키 안에 있는 값을 author라는 string파라미터에 저장한다.
    @Body('title') title: string,
    @Body('content') content: string,
  ) {
    // 생성할 포스트 데이터에 맞게 post 만듦
    const post: PostModel = {
      id: posts[posts.length - 1].id + 1,
      author,
      title,
      content,
      likeCount: 0,
      commentCount: 0,
    };

    // posts는 기존의 posts와 새로 만든 post를 넣는다.
    posts = [...posts, post];

    // 응답은 새로 만든 post만 반환한다.
    // 허용되는 정보 안에서 최소한의 데이터를 반환해주는것이 가장 좋다.
    // 최소한의 정보를 주되, 꼭 필요한 정보는 모두 담아서 반환을 해줘야함.
    // 이유 : 서버를 클라우드에 올리면 데이터를 얼마나 보냈냐에 따라서 과금을 함.
    return post; // (201 Created)
  }

  // 4) PUT /posts
  //    id에 해당되는 POST를 변경한다
  @Put(':id')
  putPost(
    @Param('id') id: string,
    // 변경하고 싶은 요소만 따로 받아서 요청을 보내면 되는데, 어떤요소를 변경하고싶은지 모름
    // 그래서 물음표를 붙여줘야함
    @Body('author') author?: string,
    @Body('title') title?: string,
    @Body('content') content?: string,
  ) {
    const post = posts.find((post) => post.id === +id);

    if (!post) {
      throw new NotFoundException();
    }
    if (author) {
      post.author = author;
    }
    if (title) {
      post.title = title;
    }
    if (content) {
      post.content = content;
    }

    posts = posts.map((prevPost) => (prevPost.id === +id ? post : prevPost));
    return post;
  }

  // 5) DELETE /posts/:id
  //    id에 해당되는 post를 삭제한다
  @Delete(':id')
  deletePost(@Param('id') id: string) {
    // id가 없다면 NotFoundException를 던지는 로직
    const post = posts.find((post) => post.id === +id);
    if (!post) {
      throw new NotFoundException();
    }
    // id가 있으면 posts에 필터해서 삭제함
    posts = posts.filter((post) => post.id !== +id);
    // 삭제한 포스트의 id를 반환함
    return id;
  }
}

 

 

3. 기본적으로 제공되는 Exception들 찾는 곳

NestJS에서 NotFoundException를 기본적으로 빌트인 되어 있는 에러들이 존재함
https://docs.nestjs.com/exception-filters#built-in-http-exceptions

자주 사용하는 exception

  • BadRequestException
  • UnauthorizedException
  • NotFoundException
  • ForbiddenException

주의점

작성하는 코드, 변수들은 다 메모리에 존재하는 값들이다.

즉, 서버가 재실행될때마다, 코드 변경이라도 조금이라도 하면 재시작되어 Post요청을해서 새로운 데이터를 넣었던 것들이 전부 다 리셋이 된다,,

하드웨어 설계상 그렇다

나중에 데이터베이스와 타입ORM을 배우면서 서버가 재시작되어도 데이터를 유지할 수 있는 방법을 배울 예정

 

 

 

 

728x90
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유