1. Issue Description
프로젝트에서 정의했던 mutation 테스트 시 필드에 null이 들어오는 이슈 발생
▶ mutation 정의
type Mutation {
signup(input: SignupRequestDto!): ApiResponseDto!
}
input SignupRequestDto {
email: String!
password: String!
nickname: String!
}
type ApiResponseDto {
message: String!
}
▶ Altair에서 테스트 했던 mutation
mutation {
signup(
input: {
email: "string",
password: "string",
nickname: "string"
}
)
{
message
}
}
▶ 발생한 예외
jakarta.validation.ConstraintViolationException:
signup.signupRequestDto.password: 비밀번호 칸은 비울 수 없습니다.,
signup.signupRequestDto.email: 이메일 칸은 비울 수 없습니다.,
signup.signupRequestDto.nickname: 닉네임 칸은 비울 수 없습니다.
2. 원인 추론
(1) validation의 문제인지 다른 문제인지 확인
@valid 삭제하고 다시 테스트
// @Valid 삭제한 코드
@MutationMapping
public ApiResponseDto signup(@Argument("input") SignupRequestDto signupRequestDto) {
System.out.println(signupRequestDto.getEmail());
System.out.println(signupRequestDto.getPassword());
System.out.println(signupRequestDto.getNickname());
memberService.signup(signupRequestDto);
return new ApiResponseDto("회원가입이 완료되었습니다.");
}
결과
null
null
null
→ validation의 문제는 아닌 것 같다.
(2) Debugging 하기
디버깅을 해보니 Spring Boot Request까지는 필드가 들어온다. 요청했던 json 형식의 text가 key, value 값으로 잘 나뉘어지는 것도 확인할 수 있었다. 다만, Request와 자바로 정의한 Dto를 서로 맵핑해줄 때 갑자기 null이 되어버렸다.
→ 맵핑에서 문제가 생기는 것으로 판단
→ 이제 문제: 맵핑에서 문제가 왜 생기는지를 모른다. 맵핑하려면 뭐가 필요한데 내가 그걸 안해줬을 가능성이 높다.
(3) 구글링
→ 구글링을 해봐도 잘 나오지를 않았다.
- 검색어 : graphql null mutation
- 대부분 스키마 파일과 리졸버에서 정의한 메서드와 인자의 이름이 일치하지 않는 경우가 많았다. 하지만 나에게 적용할 수 있는 케이스는 아니었다.
(4) Github에서 나랑 비슷한 사양의 코드 찾기
GraphQL이 Spring Boot 2와 3에서 코드가 서로 다르고(정확히는 3부터 boot starter에 GraphQL 라이브러리가 생겼는데 이 라이브러리가 전에 2에서 외부에서 끌어쓰던 라이브러리와는 코드가 일부 다른 것으로 알고 있다.) 라이브러리도 다양하기 때문에 내 사양에 맞는 코드를 찾는 것이 중요했다.
▶ 검색어 : Spring Boot 3 GraphQL
코드를 찾고 나랑 뭐가 다른지 비교하다가 DTO에 @Data 어노테이션이 있는 것을 발견했다.
@Data 어노테이션이란?
@Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor를 합쳐 놓은 어노테이션이다. 주로 DTO에 많이 쓴다고 한다.
내 DTO에는 @Getter 어노테이션만 달아준 상태였다.
→ 기존 @Getter 어노테이션을 지우고 @Data 어노테이션으로 바꾸어 다시 테스트
하지만!
- @Data의 모든 기능이 필요한 것이 아니었고
- 어떤 어노테이션으로 인해 맵핑이 가능했는지 알아야 하므로 @Data를 제거하고 @Data가 가지고 있는 여러 어노테이션을 넣으면서 테스트 했더니 @Setter 어노테이션이 달리니까 맵핑이 가능했다.
3. 결과
나중에 Spring DTO mapping Setter로 검색해서 알아본 결과,
Spring에서는 클라이언트에서 JSON 형식으로 Request를 보낼 때, Setter와 기본 생성자를 사용하여 DTO와 맵핑한다.
는 사실을 알 수 있었다.
'STUDY > Trouble Shooting' 카테고리의 다른 글
Timestamped ZonedDateTime 오류 (0) | 2024.05.22 |
---|---|
Redis Docker Container와 Spring Boot 연결이 안 되는 오류 (0) | 2024.05.22 |
만료된 토큰에서 토큰에 저장된 정보를 가져올 수 없는 오류 (0) | 2024.05.22 |
Slack Webhook을 이용한 메시지 미리보기가 안되는 오류 (0) | 2024.05.22 |
Docker에서 Spring Boot 프로젝트 build 시 GraphQL 요청을 보내지 못하는 오류 (0) | 2024.04.18 |