やりたいこと
JSON のウェブから取得して、ほしいデータだけを CSV に書き出す。
手順
まずは、JSON の中身を確認する
JSONPlaceholder というサイトから色々な JSON 提供している。
今回は ToDo リストを使う。
それでは、JSON の中身を確認。
[
{
userId: 1,
id: 1,
title: "delectus aut autem",
completed: false
},
{
userId: 1,
id: 2,
title: "quis ut nam facilis et officia qui",
completed: false
},
{
userId: 1,
id: 3,
title: "fugiat veniam minus",
completed: false
},
... と続く
ふむふむ。
userId
、id
、title
、completed
がワンセットでリピートしてるのね。
JSON と Go の構造を合わせて struct を作る
ネストがなくシンプルの構造だ。
type ToDo struct {
UserID int
ID int
Title string
Body string
}
JSON データは、この構造がスライス []ToDo
で表現されていることになる
ウェブから JSON を取得する
GET リクエストして、問題なければレスポンス BODY を読む。
url := "https://jsonplaceholder.typicode.com/posts"
res, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
log.Fatal(err)
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatal(err)
}
Unmarshal
でJSON → Go 構造に変換
Unmarshal
の第2引数にはポインタを渡す
そうしないとエラーになる
Ref: Unmarshal
var jsonData []ToDo
err = json.Unmarshal(body, &jsonData)
if err != nil {
log.Fatal(err)
}
CSV への書き込み
UserID
はいらないので、CSV には出力しない。
どこでも利用する予定がなければ、Unmarshal
で読み込まないこともできる。
csvFile, err := os.Create("./data.csv")
if err != nil {
log.Fatal(err)
}
defer csvFile.Close()
writer := csv.NewWriter(csvFile)
for _, oneToDo := range jsonData {
var row []string
row = append(row, strconv.Itoa(oneToDo.Id))
row = append(row, oneToDo.Title)
row = append(row, oneToDo.Body)
writer.Write(row)
}
writer.Flush()
まとめ
読み込む JSON に合った struct
ができれば、Unmarshal
するだけだから簡単だ。