프로그래밍백엔드 Go 개발자

Go에서 JSON (encoding/json) 작업은 어떻게 이루어지나요: 직렬화의 특징, struct의 태그 특징, 마샬링/언마샬링 시 자주 발생하는 문제와 우회 방법은 무엇인가요?

Hintsage AI 어시스턴트로 면접 통과

답변.

Go에서 JSON 마샬링은 표준적으로 encoding/json 패키지를 통해 구현됩니다. 직렬화할 수 있는 건 공개된 (대문자로 시작하는) 구조체 필드만 가능합니다. 이름 관리 및 처리는 struct 태그를 통해 수행합니다:

type User struct { ID int `json:"id"` Name string `json:"name,omitempty"` Age int `json:"age,string"` }
  • omitempty는 필드의 값이 0일 경우 해당 필드를 제외합니다;
  • string은 값이 숫자일지라도 문자열로 직렬화합니다.

직렬화 예제:

user := User{ID: 1, Name: "오лег"} b, _ := json.Marshal(user) fmt.Println(string(b)) // {"id":1,"name":"오лег","age":"0"}

JSON 파싱 예제

var u User json.Unmarshal([]byte('{"id":2,"name":"이반"}'), &u)

트릭 질문.

비노출 (소문자로 시작하는) 구조체 필드는 JSON 마샬링 시 어떻게 직렬화되나요?

올바른 답변: 이들은 무시되며, 직렬화에는 공개된 (대문자로 시작하는) 필드만 포함됩니다. 이로 인해 API가 종종 갑자기 중단됩니다:

type Foo struct { bar int // 직렬화되지 않음! }

주제의 미세한 차이를 모른 채 겪은 실제 오류 사례.


사례

백엔드에서 불완전한 JSON 객체를 반환했습니다. 필요한 필드 중 일부는 비노출 상태였기 때문에 고객이 이들 필드를 볼 수 없었습니다. 이를 확인하는 데 며칠이 걸렸습니다.


사례

API 응답에서 필드에 omitempty 구문이 포함되어 있었으나 때때로 비어있는 값이 도착했습니다. 왜냐하면 슬라이스에 대한 널 값은 nil이며 빈 슬라이스가 아니기 때문입니다. 고객은 빈 배열 [] 대신 null을 받았고 파싱 시 오류가 발생했습니다.


사례

프로젝트에서 map[문자열]인터페이스를 통해 구조체에 동적 필드를 추가하려고 했으나 커스텀 UnmarshalJSON을 구현하는 것을 잊어버려 데이터 일부가 "사라졌습니다". 고객 데이터는 사라졌고 수동으로 백업으로 복구되었습니다.