Go JSON v2 전환, null과 생략 규칙 점검
Go의 새 JSON API가 GeekNews에 소개되면서 기존 서버 코드를 어떻게 옮길지 살펴볼 시점입니다. Go 공식 가이드는 encoding/json/v2를 Go 1.27에 도입된 패키지로 설명합니다. 이 글에서는 전환 전에 확인할 응답 형식과 입력 처리 규칙을 정리합니다.
핵심 요약
- 기존
encoding/json을 반드시 교체해야 하는 것은 아닙니다. - 새 기본값에서는 nil 슬라이스·맵의 출력과 잘못된 입력의 처리 방식이 달라집니다.
omitempty를 붙인 숫자·불리언 필드는 생략 여부를 다시 확인하세요.- 권장 순서는 응답 계약 기록, 비교 테스트, 작은 범위 전환, 배포 후 확인입니다.
전환 여부는 응답 계약부터 판단하세요
Go 공식 가이드는 기존 패키지가 호환성 약속의 적용 대상이며 계속 사용할 수 있다고 명시합니다. 새 API를 쓴다는 이유만으로 모든 서비스를 한꺼번에 바꿀 필요는 없습니다. 단순한 Marshal 호출은 import 경로 변경 후에도 컴파일될 수 있지만, 출력의 의미까지 같다는 뜻은 아닙니다. Go 공식 전환 가이드
먼저 전환 목적을 문장으로 적어보세요. 새 API의 입출력 방식을 활용하려는지, 모호한 입력을 거부하려는지, 기존 서비스의 특정 문제를 해결하려는지 구분하는 것입니다. 목표가 불분명하다면 응답 계약을 정리하는 작업부터 진행하는 편을 권합니다.
여기서 응답 계약은 클라이언트와 약속한 데이터 모양입니다. 목록이 없을 때 null을 보내는지, 빈 목록을 보내는지, 아예 필드를 생략하는지 항목별로 기록하세요. 이 기록을 전환 전후 비교의 기준으로 삼으면 됩니다.
nil과 생략 규칙을 따로 확인하세요
공식 문서의 기본 동작을 기준으로 점검 대상을 나누면 다음과 같습니다. 사용자 정의 직렬화나 별도 옵션이 있는 코드는 그 설정도 함께 확인해야 합니다.
| 점검 대상 | 확인할 변화 | 리뷰 질문 |
|---|---|---|
| nil 슬라이스 | 기존 null에서 v2의 빈 배열로 변경 | 호출자가 두 상태를 구분하는가? |
| nil 맵 | 기존 null에서 v2의 빈 객체로 변경 | 빈 객체를 유효한 설정으로 보는가? |
숫자·불리언의 omitempty | v2에서는 0과 false가 생략되지 않음 | 미지정과 명시적 값의 차이가 필요한가? |
omitzero | Go 영값이나 IsZero 판단을 기준으로 생략 | 필드의 의도와 기준이 일치하는가? |
앞의 nil 변화는 전환 가이드, 생략 조건은 v2 패키지 문서에 근거합니다. v2의 omitempty는 JSON으로 표현했을 때 null 또는 빈 문자열·객체·배열인지 판단합니다. Go 값이 영값인지를 보는 omitzero와 기준이 다릅니다.
필드를 무조건 생략하도록 고치기보다 API의 의미를 먼저 정하세요. 예를 들어 설정 변경 요청이라면 ‘항목 없음’과 ‘명시적으로 끄기’를 같은 의미로 취급해도 되는지 리뷰 질문으로 남길 수 있습니다. 이 예시는 점검 관점이며 특정 서비스의 동작을 가정한 설명은 아닙니다.
엄격해진 입력 처리를 테스트에 넣으세요
v2는 기본적으로 잘못된 UTF-8과 객체 안의 중복 이름을 오류로 처리합니다. 기존 패키지와의 차이는 공식 전환 가이드에 정리돼 있습니다. 정상 데이터만 비교하지 말고 거부할 입력도 테스트 목록에 넣으세요. Go 공식 전환 가이드
중복 이름은 단순한 표기 문제가 아닙니다. JSON 표준인 RFC 8259는 객체의 이름이 고유해야 한다고 권고하며, 중복일 때 수신 구현마다 마지막 값을 사용하거나 오류를 내는 등 처리가 달라질 수 있다고 설명합니다. 따라서 같은 입력에 대한 해석이 일관적인지 확인하는 것이 핵심입니다. JSON 표준의 객체 규칙
권장 검증 방식은 실패 결과도 계약으로 다루는 것입니다. 입력 거부 시 호출자에게 어떤 응답을 줄지, 재시도할 대상인지, 로그에서 원인을 구분할 수 있는지 함께 정하세요. 오류가 생겼다는 사실만으로 새 동작이 잘못됐다고 결론 내리지 말고, 의도한 거부인지부터 판단합니다.
작은 범위로 옮기는 실전 순서
다음은 공식 동작 차이를 바탕으로 구성한 권장 작업 순서입니다. 직접 실행한 성능 측정이나 설치 후기는 아닙니다.
- 대상을 좁힙니다. 변경할 API와 사용하는 JSON 라이브러리를 적고, 요청·응답을 받는 클라이언트를 확인합니다.
- 비교 자료를 만듭니다. 민감정보를 제거한 정상 데이터와 nil, 빈 값, 생략 필드, 중복 이름을 준비합니다.
- 기대 결과를 먼저 적습니다. 유지할 동작과 의도적으로 바꿀 동작을 나눠 코드 리뷰에 첨부합니다.
- 호환 옵션을 검토합니다. 공식 가이드는 v2 호출에
jsonv1.DefaultOptionsV1()을 전달해 v1 동작을 지정하는 방법을 제공합니다. 이를 출발점으로 쓸지 판단하세요. - 호출자까지 확인합니다. 서버 테스트뿐 아니라 응답을 소비하는 쪽의 확인 결과를 배포 조건에 포함합니다.
호환 옵션을 선택했다면 이유와 제거 조건도 기록하는 편을 권합니다. ‘기존 앱이 null을 기대하므로 유지’처럼 구체적인 설명이 있으면 다음 변경에서 판단하기 쉽습니다. 호환 옵션의 공식 설명
외부 JSON 라이브러리는 별도로 검증하세요
ByteDance의 Sonic 호환성 문서는 기존 표준 API와 직접 사용하는 v2 API를 구분하며, ConfigStd가 목표로 삼는 것은 기존 v1 동작이라고 설명합니다. ‘Go를 지원한다’는 문구와 ‘v2의 새 기본값을 재현한다’는 문구를 같은 의미로 읽으면 안 됩니다. Sonic 호환성 문서
또한 열람한 문서의 검증 근거는 Go 1.27rc2 기준이며, 최종 툴체인 재검증 필요성을 명시합니다. 이 자료를 현재 모든 조합의 호환성 보증으로 확대하지 마세요. 프로젝트에서 실제 고정한 Go와 라이브러리 버전을 기준으로 확인 결과를 남기는 것이 좋습니다.
정리
Go JSON v2 전환은 import 경로보다 데이터 의미를 먼저 검토할 작업입니다. 오늘 시작한다면 외부에 공개된 응답 하나를 골라 nil, 빈 값, 필드 생략의 기대 결과를 적어보세요. 그 기준으로 새 동작을 비교한 뒤 전환 범위를 넓히기를 권합니다.
참고 자료
관련글
댓글
댓글을 불러오는 중입니다...