어떤 API 에 쿼리 파라미터로 전달해야 하는 항목 중 파라미터를 다르게 전달해야 하는 경우가 있다고 생각해보자.

예를 들어, keywordType 을 keyword_type 이라는 이름으로 전달해야 하는 상황이라고 생각해보자.

 

@SpringQueryMap 을 사용하면 아래와 같이 작성할 수 있을 것이다.

@FeignClient
public interface MemberApiClient {
    @GetMapping(value = "/users")
    UserResponseDto userSearch(@SpringQueryMap UserRequestDto request);
}
@Builder
@Getter
public class UserRequestDto {
    @Builder.Default
    private UserKeywordType keywordType = UserKeywordType.ID;

    public enum UserKeywordType {
        NAME, ID, DOMAIN, EMAIL, REGISTRATION_NO, PHONE, SNS_MAIL,
    }
}

위와 같이 작성 후 전달하게 되면 쿼리 파라미터가 keywordType 으로 그대로 전달하게 된다. 여기서 파라미터를 다르게 전달하려면 @Param 을 사용해야 한다. 그러면 아래와 같이 생각해볼 수도 있다.

@Builder
@Getter
public class UserRequestDto {
    @Builder.Default
    @Param("keyword_type")
    private UserKeywordType keywordType = UserKeywordType.ID;

    public enum UserKeywordType {
        NAME, ID, DOMAIN, EMAIL, REGISTRATION_NO, PHONE, SNS_MAIL,
    }
}

하지만 위 코드는 작동하지 않는다. 그대로 keywordType 으로 전달하게 된다.

Feign은 QueryMapEncoder에서 요청 파라미터를 인코딩하게 되는데 여기서 아래와 같은 부분이 있다.

위의 Param Annotation 클래스는 Feign 에서 제공한다. 해당 Annotation 클래스를 이용하면 value 메서드를 참조하여 Propery Name 으로 대신 넣어주게 된다.

 

위의 코드를 기준으로 말하자면 pd 변수는 keywordType 의 PropertyDescriptor 이고, 이것의 getReadMethod() 는 keywordType 의 getter 인 getKeywordType() 이 된다. 즉, Param Annotation 클래스는 getKeywordType() 에서 찾게 되므로 아래와 같이 작성해야 한다.

@Builder
public class UserRequestDto {
    @Builder.Default
    @Getter(onMethod_ = {@Param("keyword_type")})
    private UserKeywordType keywordType = UserKeywordType.ID;

    public enum UserKeywordType {
        NAME, ID, DOMAIN, EMAIL, REGISTRATION_NO, PHONE, SNS_MAIL,
    }
}

위의 UserRequestDto 클래스는 Lombok 의 @Getter 를 사용하고 있으므로 onMethod Property 를 사용해서 getter 메서드의 Annotation 을 추가할 수 있다. 따라서 이렇게 작성하고 실제로 요청을 전달하면 해결이 가능하다.