낙서장이자 오답 노트이자 컨닝 페이퍼
패스트캠퍼스 환급챌린지 3일차 : 코드팩토리의 백엔드 아카데미 : 한 번에 끝내는 NestJS 패키지 - 기초부터 MSA까지 강의 후기 본문
패스트캠퍼스 환급챌린지 3일차 : 코드팩토리의 백엔드 아카데미 : 한 번에 끝내는 NestJS 패키지 - 기초부터 MSA까지 강의 후기
NangIn 2025. 4. 3. 19:27본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.
강의 내용 정리
데이터 구조 & 초기 세팅
Movie 인터페이스 정의
interface Movie {
id: number;
title: string;
}
초기 데이터 및 ID 카운터
private movies: Movie[] = [
{ id: 1, title: 'Harry Potter' },
{ id: 2, title: 'Lord of the Rings' }
];
private idCounter = 3;
GET /movie - 영화 전체 목록 조회
문제점
- 기존에는 랜덤 데이터를 반환했기 때문에 일관성과 영속성이 부족.
해결책
- 메모리 기반 배열을 활용하여 movies 데이터를 관리.
구현 코드
@Get()
getMovies() {
return this.movies;
}
GET /movie/:id - 특정 영화 조회
목적
- 특정 id에 해당하는 영화 조회.
- 존재하지 않을 경우 404 Not Found 에러 처리 필요.
주요 개념
- @Param(): URL 경로의 패스 파라미터를 추출.
- 에러 처리: new Error() 사용 시 500 → NestJS의 NotFoundException 사용 권장.
구현 코드
@Get(':id')
getMovie(@Param('id') id: string) {
const movie = this.movies.find((m) => m.id === +id);
if (!movie) throw new NotFoundException('존재하지 않는 id의 영화입니다.');
return movie;
}
POST /movie - 영화 생성
목적
- 클라이언트로부터 title를 받아서 영화 생성
- 서버에서 자동으로 id 생성
- 새로 생성된 영화 객체를 그대로 반환 필요 → 클라이언트가 id를 추적
주요 개념
- POST는 신규 리소스 생성을 위한 요청이므로 패스 파라미터가 필요 없음.
- NestJS에서는 @Body() 데코레이터로 요청 바디 데이터 수신 가능.
구현 코드
@Post()
createMovie(@Body('title') title: string) {
const movie: Movie = {
id: this.idCounter++,
title,
};
this.movies.push(movie);
return movie;
}
PATCH /movie/:id - 영화 정보 수정
목적
- 기존 영화의 일부 정보 수정 (여기선 title만 변경).
- 수정 완료된 영화 객체 반환 → 클라이언트가 id를 추적
주요 개념
- 왜 패스 파라미터가 필요한가?
- 수정하려면 대상 리소스를 알아야 하므로 id 필요
- 반대로 POST는 새 데이터 생성이므로 id 필요 없음
구현 코드
@Patch(':id')
patchMovie(@Param('id') id: string, @Body('title') title: string) {
const movie = this.movies.find((m) => m.id === +id);
if (!movie) throw new NotFoundException('존재하지 않는 영화입니다.');
Object.assign(movie, { title });
return movie;
}
DELETE /movie/:id - 영화 삭제
목적
- 특정 ID의 영화를 삭제.
주요 개념
- 보안 및 신뢰성을 위해 존재하지 않는 ID에 대해서는 404 Not Found로 명확하게 피드백
구현 코드
@Delete(':id')
deleteMovie(@Param('id') id: string) {
const movieIndex = this.movies.findIndex((m) => m.id === +id);
if (movieIndex === -1) throw new NotFoundException('존재하지 않는 영화입니다.');
this.movies.splice(movieIndex, 1);
return { id: +id };
}
GET /movie + Query Parameter - 조건 검색
목적
- 쿼리 문자열을 이용하여 특정 영화 조회
- startsWith()를 활용하여 유사 검색 지원
주요 개념
- @Query('title')로 쿼리 문자열에서 필터 조건 추출
- 쿼리 파라미터란?
- URL에 ?key=value 형태로 붙는 옵션 값.
- 예: GET /movie?title=해리포터
구현 코드
@Get()
getMovies(@Query('title') title?: string) {
if (!title) return this.movies;
return this.movies.filter((m) => m.title.startsWith(title));
}
정리: @Param vs @Query vs @Body
| 구분 | 사용 목적 | 예시 | 데코레이터 |
| Param | 리소스 식별자 추출 | /movie/1 | @Param() |
| Query | 조건/필터링 | /movie?title=해리 | @Query() |
| Body | 요청 데이터 전달 | { "title": "Frozen" } | @Body() |
실무 인사이트
- NestJS는 Express 기반 프레임워크지만 훨씬 구조화되고 유지보수 친화적.
- 컨트롤러 레벨에서만 해도 @Get, @Post, @Param, @Body, @Query 등 강력한 도구 제공.
- RESTful 설계 원칙을 지키는 것만으로도 협업/유지보수/확장성이 크게 향상됨.
- 잘못된 설계 (ex. POST /movie?delete=true)는 팀 내 불신을 초래할 수 있음 → 문맥에 맞는 HTTP 메서드 사용 필수
학습 후기
NestJS로 영화 API를 구현하면서 단순한 CRUD 작업이 아닌, RESTful한 설계 방식의 중요성과 그 철학을 체감할 수 있었습니다. 특히 각 HTTP 메서드(GET, POST, PATCH, DELETE)가 어떤 의미를 갖고, 어떤 문맥에서 어떤 방식으로 설계되어야 하는지에 대해 명확하게 이해할 수 있었습니다. 단지 기능이 돌아가도록 만드는 것이 아니라, 그 기능이 왜 그렇게 설계되어야 하는지를 먼저 고민한 점이 이번 학습의 가장 큰 성과였습니다.
NestJS는 Express 기반이라는 점에서 익숙한 부분도 있었지만, @Controller, @Param, @Query, @Body와 같은 데코레이터 중심의 선언적 코드 스타일은 유지보수성과 가독성 면에서 훨씬 강력하다는 것을 느꼈습니다. 특히 NotFoundException을 활용한 에러 처리 방식은 클라이언트와의 명확한 소통을 가능하게 해주어 실무에서도 적극 활용할 수 있을 것이라 생각됩니다.
또한 @Param과 @Query의 차이, 그리고 언제 바디에서 데이터를 받아야 하는지에 대한 개념이 정리되면서 전체적인 API 설계 흐름이 머릿속에 명확하게 자리 잡혔습니다. 평소 그냥 쓰기만 했던 구조들을 이제는 설명할 수 있게 되었다는 점에서, 단순한 기술 습득이 아닌 개념 중심의 성장이라는 의미가 있었습니다.
이번 학습을 통해 ‘좋은 API란 무엇인가?’에 대한 고민을 하게 되었고, NestJS가 그 구조를 자연스럽게 따라가도록 도와주는 프레임워크라는 점이 매우 인상 깊었습니다. 이후에 데이터베이스나 인증, 미들웨어, 인터셉터 등을 다루게 되었을 때도 이런 개념 기반의 학습이 큰 도움이 될 것으로 기대하고 있습니다.
학습 인증샷




https://abit.ly/lisbva
Abit.ly 다운받기
abit.ly