티스토리 뷰
컴퓨터공학과 5584977 이지현
캡스톤디자인(1) TEAM 우연한 인연
#2.3 Movies Service part Two
* 한 가지 알아둬야 할 것!
- 우리가 파일을 저장하면 데이터베이스가 다 날아간다.
- 지금 사용하는 게 진짜 데이터베이스가 아니고 메모리 위의 데이터베이스라서 + 서버를 켜놓은 동안만 유효하다.
1. getOne 코드 개선
- 잘못된 값을 보냈을 때 적어도 에러 화면은 뜨도록 개선

지금 데이터베이스에 저장되지 않은 id 값인 111111을 GET 했을 때 Error가 뜨지만 에러인지 알 방법이 없다.
그래서 아래와 같이 getOne 코드 수정

그리고 아까처럼 없는 값을 GET하면 404 Error가 화면에 표시되고, 우리가 작성한 에러 메세지도 출력됨

2. deleteOne도 개선
- deleteOne에서는 this.getOne을 부르기만 하면 된다.

새로 저장해서 기존의 데이터베이스가 날아갔으므로 테스트하기 위해 데이터베이스를 새로 생성한다.
POST로 데이터베이스 생성 > GET으로 전체 데이터베이스 확인 > GET으로 movie id가 1인 데이터만 확인 > 데이터베이스에 없는 값인 아무 숫자값을 DELETE
데이터베이스에 없는 id를 DELETE 하려고 했을 때, 마찬가지로 404 Error가 뜨게되었다.




3. update 작성
- update 함수를 작성하고, controller에서 Patch를 수정하였다.


이번에는 헤더에 year을 2025년으로만 설정하고 PATCH 해주었음 (200 OK)

PATCH하고 실행했더니 같은 id값이 중복되어서 저장됨
이 말은 delete가 작동하지 않았다는 것이다.

* deleteOne 코드를 잘못 작성해서 수정

그리고 다시 POST > GET > PATCH > GET으로 확인하니 정상적으로 작동된다.

처음에는 id가 1인 movie의 year이 2025였는데 PATCH 후 2020으로 바뀌어서 update된 것을 확인할 수 있다.
** 이제 Service는 끝!
하지만 여기서 문제는 updateData의 유효성을 검사하지 않고 있다는 것
= 누군가가 부적절한 것을 보낼 수 있다.
예를 들어,
내 데이터에 "hacked": "by me" 같은 부적절한 것을 아무 문제 없이 추가할 수 있다.


4. updateData(movieData)의 유효성 검사
- NotFoundException과 같이 NestJS에서 기본제공하는 것을 사용할 것임
- 다음 영상에서 이어서
#2.4 DTOs and Validation Part One
- updateData와 movieData에 타입을 부여하기 위해서 서비스와 컨트롤러에서 DTO라는 것을 만들어야 한다.
DTO는 데이터 전송 객체(Data Transfer Object)이다.
1. dto 폴더 및 파일 생성

src의 movies 폴더에 dto 폴더를 생성해주고 create-movie.dto.ts 라는 이름으로 파일을 생성하였다.
create-movie.dto.ts는 기본적으로 클래스가 될 것이다.
2. CreateMovieDto 클래스 생성

CreateMovieDto class를 만들어주고 읽기 전용으로 우리가 movie에 저장할 변수들과 타입을 지정해준다.


그리고 controller의 @Post에서 movieData와 service의 create에서 movieData의 타입을 CreateMovieDto로 지정해주었다.
실행했을 때 hacked라는 정보가 아직은 그대로 저장됨


DTO를 쓰는 이유는 프로그래머로서 코드를 더 간결하게 만들 수 있도록 해준다.
그리고 NestJS가 들어오는 쿼리에 대해 유효성 검사를 할 수 있게 해준다.
이를 위해서 main.ts에 파이프라는 것을 만들 것이다. (파이프: 코드가 지나가는 곳)
3. 유효성 검사용 파이프 만들기

main 함수에 app.useGlobalPipes(new ValidationPipe()); 코드 추가
ValidationPipe는 유효성을 검사해주기 때문에 아주 유용한 코드이다.
그리고 진행하기 전에 몇 가지를 설치해주었다.
- npm i class-validator class-transformer

설치 후 CreateMovieDto를 위한 decorator 작성
- @IsString(), @IsNumber()
이 데코레이터는 class-validator에서 import 시켜주었다.
@IsString({ each: true })는 배열에 들어오는 각각을 검사한다는 의미

그리고 insomnia에서 POST로 아까와 같은 hacked 정보를 넘겨보았는데,
이번에는 400 Bad Request가 뜨면서 정보가 저장되지 않는 것을 볼 수 있다.
(title, year, genres 정보는 string/number여야 한다는 에러 메세지가 뜸)

이제 input에서도 유효성 검사를 하게 되었다.
4. ValidationPipe Option
아까 만들었던 파이프의 ValidationPipe에는 여러 옵션이 있는데, 그 중 하나가 whitelist이다.

ValidationPipe의 whitelist에 대한 설명인데, 읽어보면 true로 설정하면 아무 데코레이터도 없는 property의 object는 거를 것이라고 되어 있다. 즉, 내가 hacked by me를 보내면 이 코드는 Validator에 도달하지 않는다는 것이다.
그리고 forbidNonWhiteListed를 통해 누군가 이상한 걸 보내면 리퀘스트 자체를 막아버리도록 보안을 한 단계 업그레이드할 수 있다.

이렇게 코드를 작성하고 insomnia에서 테스트를 해 보면, 아까 없었던 "property hacked should not exist(property hacked는 존재할 수 없다)"라는 메세지도 추가되어 나온다.

그리고 ValidationPipe에 대해 한 가지 더
(+string은 string을 number로 바꿔줌) 앞에 게시물 수정))


우리가 Movie의 id를 number로 설정했는데, url에서 가져오는 값은 string이므로 service.ts에서 string으로 받은 id값을 +id를 통해 number로 바꿔주었었다. 이는 별로 좋은 방법이 아니다.
그래서 우리는 transform이라는 옵션을 사용할 것이다.
transform은 유저가 보낸 것을 우리가 원하는 타입으로 변환해 주는 것이다.

따라서 ValidationPipe에 transform: true를 추가해주고, 컨트롤러와 서비스에서 id 타입을 전부 number로 바꿔주었다. (string을 number로 바꿔줬던 +id도 id로 변경)
그리고 console.log()를 통해 movieId의 타입을 출력해보면 number라고 잘 나온다.


∴ NestJS는 타입을 받아서 넘겨줄 때 자동으로 타입도 변환해준다.
'캡스톤디자인(1) > 공부' 카테고리의 다른 글
| 캡스톤디자인(1) NestJS 공부 4 (0) | 2022.11.07 |
|---|---|
| 캡스톤디자인(1) - NestJS 공부2 (0) | 2022.10.14 |
| 캡스톤디자인(1) - NestJS 공부 1 (0) | 2022.10.13 |
