go에서 json을 파싱할때 struct 구조를 모르거나,
키값 하나만 필요한데 struct는 너무 커서 곤란할 때가 있다.
그럴 땐 interface를 통해 파싱하면 간편하다.
exampleJson이라는 변수에 json string이 담겨있다고 가정했을 때,
아래 코드로 파싱 가능하다.
const exampleJson = `{"kind":"Event","apiVersion":"events.k8s.io/v1"}`
var result map[string]interface{}
if err := json.Unmarshal([]byte(exampleJson), &result); err != nil {
panic(err)
}
fmt.Println(result["kind"]) // Event 출력
fmt.Println(result["apiVersion"]) // events.k8s.io/v1 출력
만약 value값에 또 key, value형식으로 되어있다면 아래와 같이 해주면 된다.
const exampleJson = `{"kind":"Event",` +
`"apiVersion":"events.k8s.io/v1",` +
`"metadata":{"name":"swlee-event-test-53009236","namespace":"default"}}`
var result map[string]interface{}
if err := json.Unmarshal([]byte(exampleJson), &result); err != nil {
panic(err)
}
fmt.Println(result["metadata"].(map[string]interface{})["name"]) // swlee-event-test-53009236 출력
fmt.Println(result["metadata"].(map[string]interface{})["namespace"]) // default 출력
만약 그 아래에 또 있다면, 위 처럼 반복하면된다.
next_result := result["상위 키 값"].(map[string]interface{}) 의 형태로 새로운 변수를 만든 뒤
next_result["하위 키 값"] 의 형태로 호출하면 된다.
참고로 string 타입으로 변환하고 싶으면 맨 마지막에 .(string)으로 하면 된다.
e.g.)
next_result := result["상위 키 값"].(map[string]interface{})["하위 키 값"].(string)
이를 좀 더 간편하게 써보기 위해 함수화 시켜보았다.
package main
import (
"encoding/json"
"fmt"
)
const exampleJson = `{"kind":"Event","apiVersion":"events.k8s.io/v1","metadata":{"name":"namespaceclaim-53009236","namespace":"default","creationTimestamp":null,"labels":{"hypercloud":"claim"}},` +
`"eventTime":"2021-10-20T04:38:47.827281Z","reportingController":"swlee-controller","reportingInstance":"swlee-instance","action":"testAction","reason":"dangan","regarding":{"namespace":"default"},"type":"Normal","deprecatedSource":{},"deprecatedFirstTimestamp":null,"deprecatedLastTimestamp":null}`
func main() {
var result map[string]interface{}
if err := json.Unmarshal([]byte(exampleJson), &result); err != nil {
panic(err)
}
fmt.Println(valueFromKey(result, "metadata", "name"))
fmt.Println(valueFromKey(result, "reportingController"))
fmt.Println(valueFromKey(result, "reportingInstance"))
fmt.Println(valueFromKey(result, "action"))
fmt.Println(valueFromKey(result, "reason"))
}
func valueFromKey(r map[string]interface{}, key ...string) string {
if len(key) == 1 {
return r[key[0]].(string)
} else if len(key) == 2 {
return r[key[0]].(map[string]interface{})[key[1]].(string)
} else {
fmt.Errorf("Not Support for 3 or more parameters.")
}
return ""
}
내가 임의로 만든 event 객체를 파싱해본 코드이다
하드코딩으로 2단계 키 값까지만 다뤘다.
결과는 아래와 같이 나온다
root@swlee:~/parsing-test# go run main.go
namespaceclaim-53009236
swlee-controller
swlee-instance
testAction
dangan
'공부 > Go' 카테고리의 다른 글
Go API server template + Dockerfile & yaml (0) | 2022.07.09 |
---|---|
golang convert []byte(byte array) to map[string]interface{} (0) | 2022.06.22 |
golang context 개념 (0) | 2021.09.30 |
golang http 코드 예시(golang http skeleton code) (0) | 2021.09.20 |
go mod download dial tcp i/o timeout 오류 (0) | 2021.09.06 |