使用 Go 解析 JSON API 响应
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
(您可以在这里找到我的原文 - data-gulu.com)
介绍
当您将模型结果托管为微服务,或从网站抓取数据时,您经常会遇到需要处理 RESTful API JSON 对象的情况。本文将向您展示如何在 Go 中轻松处理 JSON 数据。
概述
- 从示例 API 托管站点获取 JSON 响应 - 请求
- 从响应生成 Go 结构体 - json-to-go
- 将 JSON 响应反序列化为 Go 结构体
- 遍历结构体并打印结果中的数据
获取请求
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
resp, err := http.Get("https://reqres.in/api/users?page=2")
if err != nil {
fmt.Println("No response from request")
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) // response body is []byte
fmt.Println(string(body)) // convert to string before print
}
结果 JSON
{"page":2,"per_page":6,"total":12,"total_pages":2,"data":[{"id":7,"email":"michael.lawson@reqres.in","first_name":"Michael","last_name":"Lawson","avatar":"https://reqres.in/img/faces/7-image.jpg"},{"id":8,"email":"lindsay.ferguson@reqres.in","first_name":"Lindsay","last_name":"Ferguson","avatar":"https://reqres.in/img/faces/8-image.jpg"},{"id":9,"email":"tobias.funke@reqres.in","first_name":"Tobias","last_name":"Funke","avatar":"https://reqres.in/img/faces/9-image.jpg"},{"id":10,"email":"byron.fields@reqres.in","first_name":"Byron","last_name":"Fields","avatar":"https://reqres.in/img/faces/10-image.jpg"},{"id":11,"email":"george.edwards@reqres.in","first_name":"George","last_name":"Edwards","avatar":"https://reqres.in/img/faces/11-image.jpg"},{"id":12,"email":"rachel.howell@reqres.in","first_name":"Rachel","last_name":"Howell","avatar":"https://reqres.in/img/faces/12-image.jpg"}],"support":{"url":"https://reqres.in/#support-heading","text":"To keep ReqRes free, contributions towards server costs are appreciated!"}}
转换 JSON 响应
您可以访问此网站 - JSON,轻松地将 JSON 响应转换为 Go 结构体。
将 JSON 反序列化为 Go 结构体
然后,您可以将[]byteGET 响应中的数据反序列化为Response我们刚刚自动生成的结构体。
// Generated go struct
type Response struct {
Page int `json:"page"`
PerPage int `json:"per_page"`
Total int `json:"total"`
TotalPages int `json:"total_pages"`
Data []struct {
ID int `json:"id"`
Email string `json:"email"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Avatar string `json:"avatar"`
} `json:"data"`
Support struct {
URL string `json:"url"`
Text string `json:"text"`
} `json:"support"`
}
// snippet only
var result Response
if err := json.Unmarshal(body, &result); err != nil { // Parse []byte to go struct pointer
fmt.Println("Can not unmarshal JSON")
}
fmt.Println(PrettyPrint(result))
响应结构预览(部分)
{
"page": 2,
"per_page": 6,
"total": 12,
"total_pages": 2,
"data": [
{
"id": 7,
"email": "michael.lawson@reqres.in",
"first_name": "Michael",
"last_name": "Lawson",
"avatar": "https://reqres.in/img/faces/7-image.jpg"
},
{
"id": 8,
"email": "lindsay.ferguson@reqres.in",
"first_name": "Lindsay",
"last_name": "Ferguson",
"avatar": "https://reqres.in/img/faces/8-image.jpg"
}
]
}
最后遍历数据节点并打印出结果的 FirstName。
// Loop through the data node for the FirstName
for _, rec := range result.Data {
fmt.Println(rec.FirstName)
}
完整代码
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type Response struct {
Page int json:"page"
PerPage int json:"per_page"
Total int json:"total"
TotalPages int json:"total_pages"
Data []struct {
ID int json:"id"
Email string json:"email"
FirstName string json:"first_name"
LastName string json:"last_name"
Avatar string json:"avatar"
} json:"data"
Support struct {
URL string json:"url"
Text string json:"text"
} json:"support"
}
func main() {
<span class="c">// Get request</span>
<span class="n">resp</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">http</span><span class="o">.</span><span class="n">Get</span><span class="p">(</span><span class="s">"https://reqres.in/api/users?page=2"</span><span class="p">)</span>
<span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"No response from request"</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">defer</span> <span class="n">resp</span><span class="o">.</span><span class="n">Body</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span>
<span class="n">body</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">ioutil</span><span class="o">.</span><span class="n">ReadAll</span><span class="p">(</span><span class="n">resp</span><span class="o">.</span><span class="n">Body</span><span class="p">)</span> <span class="c">// response body is []byte</span>
<span class="k">var</span> <span class="n">result</span> <span class="n">Response</span>
<span class="k">if</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">json</span><span class="o">.</span><span class="n">Unmarshal</span><span class="p">(</span><span class="n">body</span><span class="p">,</span> <span class="o">&</span><span class="n">result</span><span class="p">);</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span> <span class="c">// Parse []byte to the go struct pointer</span>
<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Can not unmarshal JSON"</span><span class="p">)</span>
<span class="p">}</span>
<span class="c">// fmt.Println(PrettyPrint(result))</span>
<span class="c">// Loop through the data node for the FirstName</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">rec</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">result</span><span class="o">.</span><span class="n">Data</span> <span class="p">{</span>
<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">rec</span><span class="o">.</span><span class="n">FirstName</span><span class="p">)</span>
<span class="p">}</span>
}
// PrettyPrint to print struct in a readable way
func PrettyPrint(i interface{}) string {
s, _ := json.MarshalIndent(i, "", "\t")
return string(s)
}
演示
(您可以在这里找到我的原文 - data-gulu.com)
文章来源:https://dev.to/billylkc/parse-json-api-response-in-go-10ng

