Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] feat: 리뷰 등록 요청 dto 형식 검증 로직을 SpringBeanValidator 를 통해 구현 #668

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from

Conversation

nayonsoso
Copy link
Contributor

@nayonsoso nayonsoso commented Sep 23, 2024


🚧이 PR은 부수고, 아루 추상화 PR 이 머지되면 거기에서 새로 작업 후 다시 PR 올리겠습니다. 이런식의 변경에 동의하는지만 approve 로 알려주세요 🚧

🚀 어떤 기능을 구현했나요 ?

  • 리팩터링 전에는, 요청 '형식'에 대한 검증이 서비스 로직에 있었습니다.
  • '선택형 질문에 대한 답변에는 서술형 응답이 올 수 없다'이런 부분들 말이죠!
  • 그래서 지난 논의에서 '형식에 대한 검증은 dto 검증 로직으로 옮기자' 는 이야기가 나왔고, 저는 그 부분을 구현했습니다.

🔥 어떻게 해결했나요 ?

  • Controller 메서드의 인자에 있는 @Valid가 있으면, 해당 객체의 jakarta.validation 을 검사하여 유효한지 검사합니다.
  • 따라서 커스텀 validation 어노테이션을 만들 필요가 있었습니다.
  • 커스텀 validation 어노테이션을 만드는 방법은 아주 간단합니다!
  1. jakarta.validation.ConstraintValidator 를 구현하는 Validator 클래스 만들기
public class EitherTextOrCheckboxValidator
        implements ConstraintValidator<EitherTextOrCheckbox, ReviewAnswerRequest> {

    @Override
    public boolean isValid(ReviewAnswerRequest request, ConstraintValidatorContext context) {
        if (request.selectedOptionIds() != null) {
            return request.text() == null;
        }
        return request.text() != null;
    }
}
  1. Validator 클래스를 사용해서 검증할 대상을 표시하는 어노테이션 만들기
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EitherTextOrCheckboxValidator.class)
public @interface EitherTextOrCheckbox {

    String message() default "선택형 응답과 서술형 응답 중 하나만 입력해주세요.";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
  1. dto 에 붙여주기
  2. 서비스에 있는 형식 검증 로직 제거

🙌 이런 순서로 구현했습니다!


📝 전-후 예외 응답 내용 비교

image

image

📚 참고 자료, 할 말

응답 메서지 자체는 이전이 더 좋아보기이도 하지만!
형식에 대한 검증을 서비스 코드에서 제거했다는 것에 의의를 두고 싶습니다 ㅎㅎ

Copy link

github-actions bot commented Sep 23, 2024

Test Results

91 tests   91 ✅  3s ⏱️
33 suites   0 💤
33 files     0 ❌

Results for commit e6905d9.

♻️ This comment has been updated with latest results.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EitherTextOrCheckboxValidator.class)
public @interface EitherTextOrCheckbox {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scale이라는 타입이 추가되면 어떡해요? EitherTextOrCheckboxOrScale이라고 이름 바꿔야 하나요..? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"해당하는 질문 타입에 대해서만 답변할 수 있다" 이런 의미를 담도록 바꿔보겠습니다 ㅎㅎ

@donghoony donghoony changed the title [BE] 리뷰 등록 요청 dto 형식 검증 로직을 SpringBeanValidator 를 통해 구현 [BE] feat: 리뷰 등록 요청 dto 형식 검증 로직을 SpringBeanValidator 를 통해 구현 Sep 24, 2024
Copy link
Contributor

@Kimprodp Kimprodp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 방법은 처음 알았네요 또 하나 배우고 갑니다!
코멘트 확인만 부탁해요~

@Constraint(validatedBy = EitherTextOrCheckboxValidator.class)
public @interface EitherTextOrCheckbox {

String message() default "선택형 응답과 서술형 응답 중 하나만 입력해주세요.";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아루의 코멘트에 이어서 에러 메세지도 질문 타입 추가에 영향을 받지 않도록 수정되면 좋을 것 같아요.

@nayonsoso
Copy link
Contributor Author

@Kimprodp @donghoony

피드백 감사합니다🙇🏻‍♀️
타입의 종류에 상관없이 '한가지 종류에 대해서만 응답할 수 있다’ 는 뜻을 가질 수 있게 @OneTypeAnswer로 바꿔봤습니다.
그리고 이 어노테이션이 아무래도 커스텀 어노테이션이기 때문에 더 의미를 잘 전달하도록 메세지를 밖에서 명시하도록 바꿔봤어요.

@OneTypeAnswer(message = "한 가지 유형의 답변만 가능해요.")
public record ReviewAnswerRequest(
    // ...
) {
}

@donghoony donghoony changed the base branch from develop-x to develop October 24, 2024 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BE] 요청에 대한 검증은 spring bean validation 을 사용해서 dto 에서 수행하게 한다.
3 participants