학습
Go JSON 처리 (JSON Handling)
Go JSON 처리 (JSON Handling) — 중급
JSON 처리 (JSON Handling)
1. 도입 (왜 배워야 하는가)
JSON(JavaScript Object Notation)은 데이터 교환 형식으로, 웹 애플리케이션에서 서버와 클라이언트 간의 데이터 전송에 널리 사용됩니다. 많은 API들이 JSON 형식으로 데이터를 주고받기 때문에, 이를 잘 다룰 수 있는 능력은 매우 중요합니다. JSON을 처리하지 못하면, 외부 데이터와의 상호작용이 불가능해지고, 이는 전반적인 애플리케이션의 기능 저하를 초래할 수 있습니다. 예를 들어, 쇼핑몰 애플리케이션에서 상품 정보를 외부 API에서 받아와야 하는 경우, JSON 처리를 제대로 하지 않으면 상품 정보를 화면에 표시할 수 없습니다.
2. 핵심 개념 설명
JSON의 개념
- JSON은 키-값 쌍으로 구성된 데이터 형식으로, JavaScript에서 유래되었습니다.
- 데이터 구조를 간단명료하게 표현할 수 있어 사람과 기계가 모두 이해하기 쉽습니다.
- JSON은 마치 주소록과 같습니다. 이름, 전화번호, 이메일 주소와 같은 정보를 키-값 쌍으로 저장합니다. 주소록을 빠르게 찾아보는 것처럼 JSON을 통해 필요한 데이터를 쉽게 조회할 수 있습니다.
비유
관련 용어 정리
| 용어 | 설명 |
|---|---|
| Marshaling | Go의 데이터 구조체를 JSON 형식으로 변환하는 과정 |
| Unmarshaling | JSON 형식을 Go의 데이터 구조체로 변환하는 과정 |
3. 기본 코드 예제
아래 예제는 Go에서 JSON을 Marshal(직렬화)하고 Unmarshal(역직렬화)하는 기본적인 방법을 보여줍니다.
package main
import (
"encoding/json"
"fmt"
"log"
)
type Person struct {
Name string json:"name"
Age int json:"age"
}
func main() {
// 1. Person 구조체 생성
p := Person{Name: "Alice", Age: 30}
// 2. 구조체를 JSON으로 변환
jsonData, err := json.Marshal(p)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonData)) // {"name":"Alice","age":30}
// 3. JSON 데이터를 구조체로 변환
var p2 Person
err = json.Unmarshal(jsonData, &p2)
if err != nil {
log.Fatal(err)
}
fmt.Println(p2) // {Alice 30}
}
실행 결과
{"name":"Alice","age":30}
{Alice 30}
코드 한 줄씩 동작 설명
Person이라는 구조체를 정의합니다. 이 구조체는 이름과 나이를 담고 있습니다.p라는 변수를 생성하여Person구조체의 인스턴스를 초기화합니다.json.Marshal을 사용하여p를 JSON 형식으로 변환합니다. 이 과정에서 JSON 데이터가 생성됩니다.json.Unmarshal을 사용하여 JSON 데이터를 다시Person구조체로 변환합니다. 변환된 데이터는p2에 저장됩니다.- 잘못된 코드:
- 올바른 코드:
- 잘못된 코드:
- 올바른 코드:
- JSON은 데이터 전송에 필수적인 형식이며, Go에서 쉽게 처리할 수 있다.
- Marshal과 Unmarshal을 통해 구조체와 JSON 간의 변환이 가능하다.
- JSON의 구조체 태그 사용과 데이터 타입 일치를 항상 확인해야 한다.
- API 설계 및 RESTful 서비스 구축
- Go에서의 에러 처리 및 로깅
- 고급 JSON 처리 (중첩 구조체 및 배열)
4. 실전 활용 예제
1. API 응답 처리
예를 들어, 쇼핑몰에서 상품 목록을 가져오는 API를 호출한 뒤, JSON 데이터를 구조체로 변환하여 사용할 수 있습니다.
type Product struct {
ID int json:"id"
Name string json:"name"
Price float64 json:"price"
}
func fetchProducts() {
response, err := http.Get("https://api.example.com/products")
if err != nil {
log.Fatal(err)
}
defer response.Body.Close()
var products []Product
if err := json.NewDecoder(response.Body).Decode(&products); err != nil {
log.Fatal(err)
}
fmt.Println(products)
}
2. 데이터 저장 및 로드
JSON 파일에 데이터를 저장하고 이를 다시 로드하는 예제입니다.
func saveToFile(filename string, data interface{}) {
jsonData, err := json.Marshal(data)
if err != nil {
log.Fatal(err)
}
err = ioutil.WriteFile(filename, jsonData, 0644)
if err != nil {
log.Fatal(err)
}
}
func loadFromFile(filename string) (Person, error) {
var p Person
jsonData, err := ioutil.ReadFile(filename)
if err != nil {
return p, err
}
err = json.Unmarshal(jsonData, &p)
return p, err
}
이 두 가지 예제는 JSON을 활용하여 외부 API와 상호작용하거나 데이터를 파일에 저장할 수 있게 해줍니다.
5. 흔한 실수와 주의사항
실수 1: 구조체 태그 누락
type Person struct {
Name string
Age int
}
type Person struct {
Name string json:"name"
Age int json:"age"
}
태그를 누락하면 JSON 변환 시 필드명이 대소문자 구분으로 인해 올바르게 인식되지 않습니다.
실수 2: JSON 데이터 타입 불일치
type Product struct {
Price string json:"price" // 잘못된 타입
}
type Product struct {
Price float64 json:"price" // 올바른 타입
}
Price 필드의 타입이 JSON 응답 데이터와 맞지 않으면 Unmarshal 시 오류가 발생합니다.