JSON→Go 구조체 변환

JSON 객체(또는 JSON 배열)를 붙여넣으면 대응하는 Go struct 정의와 json 태그를 자동으로 생성합니다.

JSON에서 Go 구조체를 만들기

API 응답을 Go에서 받으려면 그 JSON에 대응하는 구조체와 json 태그를 써야 합니다. 필드가 몇 개뿐이라면 수고랄 것도 없지만, **중첩이 깊어지는 순간 타입 이름을 지어 가며 계층을 따라가는 일 자체가 품이 됩니다.** 이 도구는 붙여 넣은 JSON만으로 중첩 구조까지 포함한 정의 일습을 만들어 냅니다.

**다만 나오는 것은 「한 건의 샘플에서 추측한 타입」임을 새겨 두시기 바랍니다.** 샘플에 나타나지 않은 키는 당연히 없고, 값이 `null`이던 필드는 Go에 대응하는 널 허용 기본형이 없어 `interface{}`가 됩니다. 배열의 요소가 모두 객체라면 각 요소의 키를 합쳐 하나의 구조체로 만들고, **일부에만 있는 키에는 `omitempty`를 붙입니다.** 출력을 실제로 쓸 구조체로 다듬는 일은, 이 추측의 자취를 진짜 API 명세와 맞춰 고치는 것을 전제로 합니다.

변환하는 순서

  1. JSON을 붙여 넣습니다 객체든 배열이든 상관없으며, API 응답을 받은 그대로 넣어도 됩니다.
  2. 루트 타입의 이름을 정합니다 처음에는 `Root`입니다. **중첩된 타입의 이름은 각 속성명을 파스칼 표기로 바꿔 자동으로 붙습니다.**
  3. 생성된 구조체를 확인합니다 json 태그가 붙은 정의가 계층 순서대로 늘어섭니다.
  4. 복사해 다듬습니다 `gofmt`를 한 번 거친 뒤, `interface{}`가 된 곳과 포인터로 해야 할 곳을 실제 명세에 맞춰 고칩니다.

더 잘 활용하기 위한 팁

  • 배열의 모든 요소가 객체인 경우, 각 요소의 키를 병합하여 하나의 struct를 생성합니다. 일부 요소에만 존재하는 키에는 자동으로 `omitempty` 태그가 붙습니다.
  • 루트 타입 이름은 기본값 "Root"에서 원하는 이름으로 바꿀 수 있습니다. 중첩된 객체의 struct 이름은 해당 속성 이름을 PascalCase로 변환해 자동으로 생성됩니다.
  • Go에는 null을 허용하는 기본 타입이 없기 때문에 JSON의 null은 `interface{}`로 출력됩니다. 더 엄격하게 다루고 싶다면 포인터 타입으로 바꾸는 것을 검토해 보세요.
  • 생성 결과는 열이 가볍게 정렬된 초안입니다. 붙여넣은 뒤 `gofmt`를 실행하면 프로젝트의 표준 스타일에 맞춰 정렬됩니다.
  • API 응답 샘플 JSON을 그대로 붙여넣으면 Go 코드에서 사용할 응답용 struct의 초안을 빠르게 얻을 수 있습니다.

이럴 때 쓸 수 있습니다

API 클라이언트를 짜기 시작할 때

문서의 예시 응답을 붙여 넣으면 받는 쪽 구조체의 초안이 곧바로 손에 들어옵니다.

설정 파일을 읽어 들일 때

설정을 JSON으로 두는 경우 그 구조를 그대로 타입으로 옮길 수 있습니다.

외부 서비스의 명세를 읽어 낼 때

**겹겹이 중첩된 JSON은 구조체로 펼쳐 놓으면 훨씬 파악하기 쉬워집니다.**

테스트 픽스처를 마련할 때

실제 응답에서 타입을 먼저 뽑아 두면 모의 데이터를 쓸 때 어긋날 여지가 줄어듭니다.

Go 타입 대응 용어

구조체
Go에서 여러 필드를 하나로 묶는 타입입니다. JSON의 객체에 대응합니다.
json 태그
필드 뒤에 `json:"user_id"` 꼴로 쓰는 주석으로, **Go의 필드명과 JSON의 키가 어떻게 맞물리는지를 알려 줍니다.**
omitempty
json 태그의 옵션으로, **값이 제로값일 때 그 필드를 출력에서 뺍니다.** 널을 허용한다는 뜻이 아니라는 점은 새겨 둘 만합니다.
interface{}
어떤 값이든 받는 타입입니다. JSON의 null이나 타입이 흔들리는 필드가 여기로 떨어지므로 **생성 뒤에 다시 볼 자리를 알려 주는 표시가 됩니다.**
파스칼 표기
`UserId`처럼 단어마다 첫 글자를 대문자로 쓰는 방식입니다. Go에서는 **이 첫 대문자가 패키지 밖으로 공개한다는 뜻도 함께 지닙니다.**
포인터 타입
`*string`처럼 쓰는 타입입니다. 값이 없는 상태를 빈 문자열과 갈라놓아야 할 때 손이 갑니다.

자주 묻는 질문

샘플 응답을 보고 직접 struct를 작성하면 시간이 오래 걸리고, 필드 이름 변환 실수나 json 태그 누락이 발생하기 쉬우며 특히 중첩이 깊을수록 더 그렇습니다. 자동 생성을 이용하면 이러한 실수를 방지하고 구현 시간을 크게 단축할 수 있습니다.

JSON 키(snake_case 또는 camelCase)는 첫 글자가 대문자인 PascalCase로 변환되어 Go에서 외부로 노출 가능한(exported) 필드 이름이 됩니다. 원래의 JSON 키는 json 태그(`json:"원래_키"`)에 그대로 보존되므로 인코딩·디코딩에는 문제가 없습니다.

null 값은 `interface{}` 타입으로 출력됩니다. 배열의 일부 요소에만 존재하는 키에는 자동으로 `omitempty` 태그가 붙지만, Go 타입 자체는 제로 값(zero value)을 가질 뿐이므로 "값이 없음"과 "값이 0"을 구분해야 한다면 포인터 타입으로 바꾸는 것을 검토하세요.

소수점이 포함된 JSON 숫자는 `float64`로, 포함되지 않은 숫자는 `int`로 판정합니다. 다만 JSON의 숫자 표기에는 자릿수 정보만 남기 때문에, `int64`가 필요할 만큼 큰 값은 생성 후 수동으로 조정해 주세요.

Go에는 유니언 타입이 없기 때문에, 요소마다 타입이 다른 키는 `interface{}`로 대체됩니다. 실제 값의 타입은 실행 시점에 타입 단언(type assertion)으로 판별해야 합니다.
툴군

여담이지만 ― Go가 struct와 json 태그를 함께 쓰는 이유

Go는 정적 타입 언어이며, JSON을 다룰 때 표준 라이브러리의 `encoding/json` 패키지는 struct 필드와 json 태그 사이의 대응 관계를 참고해 인코딩·디코딩을 수행합니다. 외부 API 응답 구조를 직접 struct로 작성하는 작업은 필드가 늘어날 때마다 손이 많이 가는 반복 작업이며, 많은 Go 프로젝트에서 되풀이되어 왔습니다.

이 도구는 샘플 JSON의 구조를 분석해 대응하는 struct 정의와 json 태그를 자동으로 생성함으로써 이 반복 작업을 줄여 줍니다. 같은 분야의 유명한 도구로는 여러 언어의 타입 변환을 지원하는 quicktype이 있지만, 손에 있는 API 응답 샘플을 그대로 붙여넣어 빠르게 Go struct를 얻고 싶은 경우라면 한 가지 기능에 집중한 도구도 나름의 편리함이 있습니다.

Go에는 struct 필드를 선택적(optional)으로 만드는 언어 기능이 없기 때문에, 누락될 수 있는 JSON 필드에 대해서는 json 태그에 `omitempty`를 붙이거나 포인터 타입(`*string` 등)을 사용해 제로 값과 "값이 존재하지 않음"을 구분하는 방식이 일반적입니다. 생성된 struct는 어디까지나 구조로부터 기계적으로 추론한 결과이므로, null 허용 여부나 API의 향후 변경 가능성은 실제 명세와 대조해 수동으로 조정하는 것이 실무상의 정석입니다.