우당탕탕

[오류해결] FeignClient 요청 URL에서 = 없이 &가 나오는 현상 본문

오류해결

[오류해결] FeignClient 요청 URL에서 = 없이 &가 나오는 현상

모찌모찝 2025. 8. 11. 08:45

안녕하세요!
오늘은 업무 중에 겪었던 FeignClient 사용 시 발생한 쿼리 파라미터 처리 오류에 대해 공유드려보려고 합니다. 꽤 흔하면서도 미묘한 문제인데요, 유사한 상황을 겪고 계신 분들께 도움이 되면 좋겠습니다.

OpenFeign

문제 상황

FeignClient를 활용하여 외부 API를 호출하던 중, 아래처럼 쿼리 파라미터에 빈 문자열(””)을 넣었을 때 문제가 발생했습니다.

/test?aa&bb=1&cc=1

이상하죠?
 aa=  형태가 되었어야 하는데, 등호(=) 없이  aa  바로 뒤에  & 가 붙어버렸습니다. 이로 인해 서버 측에서는 해당 파라미터가 존재하지 않는 것으로 인식하거나, 잘못된 형식으로 처리해 버리는 문제가 생겼어요.

발생 원인

현재 회사에서는 데이터는 없지만 “정상적으로 값을 보냈다”는 의미로 빈 문자열  ""을 전달하는 전략을 사용하고 있었는데요. 문제는 FeignClient에서 이 빈 값을  key= 로 인코딩하지 않고, 그냥 키만 URL에 노출시키는 형태로 직렬화한다는 것이었습니다.

즉:
• 기대 결과:  /test?aa=&bb=1&cc=1 
• 실제 결과:  /test?aa&bb=1&cc=1 
이런 이슈는 URL 표준에서는  aa 만 있는 쿼리 문자열을 “true” 같은 boolean 플래그처럼 해석할 수 있지만, 대부분의 백엔드에서는 이렇게 전달된 파라미터를 빈 값으로 간주하지 않아서 오류가 발생합니다.

해결 방법

1. 빈 문자열 대신 명시적인 값 사용하기

빈 값을 보내야 하는 상황이라면  ""  대신  " "  (공백 문자열)이나  "empty"  같은 의미 있는 문자열을 전달하는 방식으로 수정할 수 있습니다. 서버에서도 그에 맞춰 로직을 구성하면 더욱 명확하게 동작합니다.

2. FeignClient 커스텀 인코더 구현

FeignClient에서 쿼리 파라미터 직렬화를 처리하는 부분을 커스터마이징 해서, 빈 문자열일 경우에도 반드시  key=  형태로 생성되도록 인코더를 재정의하는 방법입니다. ( 비추천합니다. 수정을 시도해 봤지만 연계가 많습니다 ^^.. )

3. 서버 측 수신 로직 보완

서버 로직에서  aa 처럼 키만 들어온 쿼리 파라미터도 빈 값으로 간주하는 로직을 추가해 호환성을 높일 수 있습니다. 클라이언트와 서버 모두에서 방어적인 처리가 가능해지는 구조입니다.

참고 사항

FeignClient의 GitHub 코드를 살펴보면서 원인을 추적하던 중, 내부 구현 파일인  QueryTemplate.java 에서 빈 값에 대해  = 를 붙이지 않고 생략하는 코드를 발견했습니다.
원래는 버그라고 생각했는데… 테스트 코드를 확인해 보니 의도된 동작이더라고요 😅
즉, FeignClient 쪽에서는 애초에  "aa" 만 보내는 걸 정상 로직으로 보고 있다는 뜻입니다.

관련 GITHUB -> https://github.com/OpenFeign/feign/blob/master/core/src/main/java/feign/template/QueryTemplate.java

위에 해결방법인 2번을 시도해 보실분은 QueryTemplate.java내에 append / create 메서드Util::isNotBlank 부분을 value -> value!= null로 바꾸시면 aa=& 형식으로 넘어가게 됩니다

    queryValues.addAll(
        StreamSupport.stream(values.spliterator(), false)
            .filter(Util::isNotBlank)
            .collect(Collectors.toList()));

마무리

FeignClient를 사용하는 마이크로서비스 환경에서 이와 같은 쿼리 파라미터 빈 값 처리 문제는 자주 발생할 수 있는 이슈입니다. 클라이언트와 서버 양쪽에서 예외 상황을 미리 고려한 설계가 중요하며, 팀 내 구현 가이드에도 명시하는 것을 권장드립니다.

이와 같은 작은 부분 하나가 실제 장애로 이어질 수 있다는 점을 고려하면, 사소한 디테일에도 주의를 기울여야 한다는 걸 다시 한번 느끼게 되네요 😊 오류해결에 도움이 되었으면 좋겠습니다. 

Comments