Rails 8 업그레이드: JSON 응답에 중복 키가 유입되는 문제

Rails 8 upgrade story: duplicate keys sneaking into our JSON responses

작성자
HackerNews
발행일
2025년 09월 25일

핵심 요약

  • 1 Rails 8 업그레이드 시 `render json:`의 성능 최적화로 인해 기존의 암묵적인 JSON 키 정규화(중복 제거) 로직이 생략되어 중복 키 문제가 발생할 수 있습니다.
  • 2 `attributes.merge(id: public_id)`와 같이 문자열 키와 심볼 키를 혼용하여 해시를 생성할 경우, Rails 8에서는 중복된 "id" 키가 포함된 JSON 응답이 생성됩니다.
  • 3 `json` 젬의 경고 기능을 활용하거나 Rails의 `disallowed_deprecation_warnings` 설정을 통해 개발 및 테스트 환경에서 중복 키 문제를 조기에 감지하고 방지할 수 있습니다.

도입

Rails 7.2.2.2에서 8.0.2.1로의 업그레이드는 겉보기에는 순조로웠으나, 배포 후 외부 API 클라이언트로부터 JSON 응답의 식별자 타입(문자열/정수) 불일치에 대한 불만이 접수되기 시작했습니다. 이는 애플리케이션의 안정성에 대한 초기 평가와 달리 예상치 못한 문제가 발생했음을 시사했습니다. 문제의 원인은 Rails 8의 변경 사항과 기존 코드의 특정 패턴이 결합되어 나타난 것이었습니다.

문제 발생 원인

문제는 ActiveRecord 객체 직렬화 코드에서 attributes.merge(id: public_id)와 같은 패턴을 사용하며 시작되었습니다. attributes는 문자열 키를 반환하고, id: public_id는 심볼 키를 사용했기에 {"id" => 1, :id => "one"}과 같이 동일한 키가 문자열과 심볼 형태로 공존하는 해시가 생성되었습니다.

Rails 버전별 동작 변화

  • Rails 7.2까지: render json: 호출 시 as_json 메서드가 내부적으로 실행되어 키를 정규화하고 중복을 제거했습니다. 이로 인해 최종 JSON 응답에는 마지막 값이 사용되어 중복 키 문제가 발생하지 않았습니다.

  • Rails 8의 변화: render json:에 옵션이 없는 경우 “고속 경로(fast path)”가 도입되었습니다. 이 경로는 as_json 호출을 생략하여 JSON 렌더링 성능을 향상시켰지만, 키 정규화 및 중복 제거 로직 또한 건너뛰게 되었습니다.

중복 키 노출 및 근본 원인

Rails 8에서는 고속 경로가 활성화되면서 {"id" => 1, :id => "one"}과 같은 혼합 키 해시가 그대로 JSON 인코더로 전달되어 {"id":1,"id":"one"}과 같이 중복 키가 포함된 JSON 응답이 생성되었습니다. 이는 개발 코드의 잠재적 버그가 Rails 7의 암묵적 동작에 의해 가려져 있다가 Rails 8의 성능 최적화로 인해 드러난 것입니다. ActiveSupport 7.1.3 변경 로그의 중복 키 방지 관련 내용은 릴리스 전 롤백되어 혼란을 야기했습니다.

문제 방지 및 감지 전략

  • 요청 스펙(Request Specs): JSON 응답 본문의 정확한 형태를 검증하는 스펙을 작성하여 중복 키를 즉시 감지합니다.

  • json 젬 활용: json 젬 2.14.0부터는 동일 키가 문자열/심볼 형태로 공존할 경우 경고를, 3.0 버전부터는 기본적으로 오류를 발생시킵니다.

  • Rails Deprecation 설정: config.active_support.disallowed_deprecation_warnings = [/detected duplicate key/]config.active_support.disallowed_deprecation = :raise 설정을 통해 json 젬의 경고를 Rails의 Deprecation 프레임워크에서 오류로 처리하여 개발 및 테스트 환경에서 조기에 문제를 발견할 수 있습니다.

결론

Rails 8 업그레이드 시 `render json:`의 성능 최적화는 긍정적인 변화였으나, 기존에 암묵적으로 작동하던 키 정규화 로직을 우회함으로써 개발 코드 내 잠재된 중복 키 문제를 드러내는 부작용을 낳았습니다. 이러한 문제는 외부 API 클라이언트에게 데이터 불일치를 야기하며 예기치 않은 오류로 이어질 수 있습니다. 따라서 업그레이드 전후로 정밀한 요청 스펙을 작성하고, `json` 젬의 경고 기능 및 Rails의 Deprecation 설정을 적극 활용하여 중복 키 문제를 사전에 감지하고 해결하는 것이 중요합니다. 이는 애플리케이션의 안정성과 데이터 일관성을 보장하는 데 필수적인 조치입니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!