fastapi의 pydantic에는 validator가 있습니다. 이 중에는 전체 schema에 대해 검증을 하는 root_validator가 있습니다. 쉽게 이야기 하면, 필드 값들의 조합이 맞는지 검증하기 위해 주로 쓰입니다. 대표적인 예로 비밀번호 재설정의 경우, 필드 2개가 있을 겁니다. 보통, newPassword, checkNewPassword로 할 텐데요. 이 두 개가 같아야 하는 검증 조건을 추가해야 할 때 쓰여요. 두 개의 필드 값을 비교하고 있잖아요? 예제를 통해 어떻게 쓰는지 간단하게 알아보겠습니다.

 


 먼저 router입니다. ResRequest 스키마를 받아서 처리를 해 주는 post /res가 있습니다.

 

 schema.py에 있는 ResRequest입니다. 정수를 받는 x와 y가 있습니다. check_x는 필드 x의 값을 체크한 다음에 값을 리턴해 줍니다. 여기에서는 -1을 곱해서 리턴해 주었습니다.

 

 다음에 @root_validator입니다. cls와 values를 받습니다. 그리고 pre=True라고 되어 있습니다. 아까 validator("x")는 pre 옵션이 붙어 있지 않았는데 무엇을 의미할까요? 이는, root validator가 res_request_validator x를 validation 하는 함수보다 먼저 수행된다는 것을 의미합니다.

 

 values.get("x"), values.get("y")로 실제 필드 이름이 x와 y에 들어있는 값을 얻어올 수 있습니다. 저는 이 두 필드값을 가지고 검증을 하였는데요. x + y가 0보다 작으면 ValueError를 떨어트렸습니다.

 

 

 이제 /res에 필드 x의 값 -20, y의 값을 3으로 하고 보내봅시다.

 

 그랬더니 422가 나오면서 x + y가 0보다 크거나 같아야 한다고 뜹니다. 왜냐하면 x와 y값을 더하면 -17 < 0이기 때문입니다. 0보다 크거나 같다는 조건을 만족하지 않습니다. 당연하게도 check_x 함수를 타지 않았습니다. 왜냐하면 먼저 root_validator가 나와버렸기 때문입니다.

 

 이제 x에 -3, y에 3을 넘겨봅시다.

 

 그러면 위와 같은 결과가 response로 날라오게 됩니다. 이건 왜일까요? root_validator가 통과하고, 필드 x에 대한 validator가 실행되었기 때문입니다. check_x는 x를 -x로 바꿔주는 것이기 때문에, request로 날라온 x 값에 -1을 곰한 3이 response로 나오게 됩니다.

 

 여기까지 정리. root_validator는 schema의 여러 필드를 한꺼번에 검증하기 위해 사용한다. 예를 들자면 필드 x와 y의 값으로 검증을 해야 할 때. 혹은 조합이 맞는지 틀린지 검증할 때 많이 사용합니다.

 


 check_x의 validator에 pre=True를 넣어주었습니다.

 

 다음에 root_validator는 pre 옵션을 넣어주지 않았습니다. 이 경우, check_x 다음에 res_request_validator 순으로 수행됩니다.

 

 이제 요청을 요래 다시 날려보겠습니다. 그러면, check_x에 의해 x가 20이 됩니다. 이 상태에서 root_validator가 수행됩니다. x와 y 값의 합은 20에 3을 더한 23입니다. 이는 0보다는 큰 수치입니다.

 

 따라서 아까와는 다르게 에러 없이 수행되었음을 볼 수 있습니다.