# Go 언어와 JSON 다루기 이 문서는 `grpccanary` 프로젝트의 **1단계: JSON 데이터 다루기**에 대한 이론적 배경과 코드 예시를 설명합니다. Go 표준 라이브러리에는 JSON 데이터를 처리하기 위한 `encoding/json` 패키지가 포함되어 있습니다. Go는 구조체 태그(Struct Tag)를 사용하여 Go 구조체와 JSON 필드를 손쉽게 매핑할 수 있는 기능을 제공합니다. 이 태그는 Go 구조체를 JSON으로 변환하거나, JSON을 Go 구조체로 변환하는 과정을 제어합니다. 이 과정을 각각 **Marshaling**과 **Unmarshaling**이라고 부릅니다. --- ## 1. `Marshal()`과 `Unmarshal()` 이해하기 Go 구조체로 JSON 데이터를 다룰 때 핵심적인 과정입니다. * **Marshaling (마샬링)**: Go 구조체(메모리 상의 데이터)를 JSON 바이트 슬라이스(`[]byte`, 텍스트 데이터)로 변환하는 과정입니다. 주로 API 응답으로 JSON을 보내거나, 데이터를 파일로 저장할 때 사용됩니다. * **Unmarshaling (언마샬링)**: JSON 문자열/바이트 데이터를 Go 구조체 또는 맵 구조로 변환하는 과정입니다. 주로 외부 API로부터 받은 JSON 데이터를 다루거나 파일에서 데이터를 읽어올 때 사용됩니다. > [!IMPORTANT] > **자주 발생하는 필드 노출(Exported) 에러** > `encoding/json` 패키지가 구조체의 필드에 접근하려면, 해당 필드는 **반드시 대문자로 시작해야 합니다 (Exported Field)**. 구조체 필드명이 소문자로 시작할 경우 JSON 파서가 이에 접근할 수 없어 Marshaling이나 Unmarshaling 시 값이 누락되는 문제가 발생합니다. --- ## 2. 실습 코드 분석 (`examples/jsonexample/json_parser.go`) 저장소의 [json_parser.go](file:///home/godopu16/PuKi/lab/canary_projects/grpccanary/examples/jsonexample/json_parser.go) 파일은 (1) `map[string]interface{}`와의 직렬화 및 (2) 구조체(`Person`)를 이용한 매핑 방식을 모두 다룹니다. ### 2.1 구조체 태그(Struct Tag) 정의 ```go type Person struct { Name string `json:"name"` Age int `json:"age"` History []string `json:"history"` } ``` * 필드 옆의 `` `json:"..."` `` 부분을 **구조체 태그**라고 부릅니다. * 이 태그는 각 필드가 JSON 데이터에서 어떤 키(key) 이름과 1:1로 매핑되는지 매칭해 줍니다. * Go 내부적으로는 대문자 필드(`Name`)를 쓰고, 외부 JSON 통신 규약으로는 소문자 키(`name`)를 사용하도록 매핑합니다. ### 2.2 Go 맵(`map`) 데이터 마샬링 ```go obj := map[string]interface{}{ "name": "홍길동", "age": 623, "history": []string{ "1900-양반집을 털었다", "1910-왕에게 잡혀감", }, } b, err := json.Marshal(obj) ``` * 구조체뿐만 아니라 동적 타입 맵인 `map[string]interface{}` 데이터도 `json.Marshal()`을 통해 쉽게 JSON 문자열로 변환할 수 있습니다. ### 2.3 구조체 언마샬링 ```go var p2 Person err = json.Unmarshal(b, &p2) ``` * `json.Unmarshal()` 함수는 바이트 슬라이스(`[]byte`) 형태의 JSON 데이터와, 결과를 받아올 변수의 **메모리 주소 포인터(`&p2`)**를 인자로 받습니다. * 포인터를 넘겨주어야 함수 내부에서 값을 정상적으로 갱신하여 반환할 수 있습니다.