#使用Go從GitHub獲取存儲庫列表
在這篇文章中,我將使用Go的net/http標準庫包,不使用任何附加庫,向GitHub API請求公共存儲庫的信息。
GitHub有一個很好的公共API稱為Search,您可以在https://developer.github.com/v3/search/#search-repositories上查看。
具體而言,我對獲取當前擁有1萬個以上星標的Go存儲庫感興趣。
我們可以傳遞一個查詢來獲取我們想要的內容。查看Search API文檔,我們需要對https://api.github.com/search/repositories
進行HTTP GET請求,並傳遞查詢?q=stars:>=10000+language:go&sort=stars&order=desc
:給我一個星標超過1萬個、使用Go語言的存儲庫,按星標數量進行排序。
最簡單的程式碼片段:我們使用net/http
中的http.Get
函數進行請求,並使用ioutil.ReadAll
函數讀取返回的內容:
package main
import (
"io/ioutil"
"log"
"net/http"
)
func main() {
res, err := http.Get("https://api.github.com/search/repositories?q=stars:>=10000+language:go&sort=stars&order=desc")
if err != nil {
log.Fatal(err)
}
body, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
}
if res.StatusCode != 200 {
log.Fatal("Unexpected status code", res.StatusCode)
}
log.Printf("Body: %s\n", body)
}
就像您所看到的那樣,它並不易於閱讀。您可以將返回的內容使用在線格式化工具來理解實際結構。 現在讓我們處理JSON並從中生成一個漂亮的表格。 如果您對JSON主題還不熟悉,可以查看我有關使用Go處理JSON的初步指南[/go-json/]。
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"text/tabwriter"
"time"
)
// Owner是存儲庫擁有者
type Owner struct {
Login string
}
// Item是單個存儲庫的數據結構
type Item struct {
ID int
Name string
FullName string `json:"full\_name"`
Owner Owner
Description string
CreatedAt string `json:"created\_at"`
StargazersCount int `json:"stargazers\_count"`
}
// JSONData包含GitHub API的響應
type JSONData struct {
Count int `json:"total\_count"`
Items []Item
}
func main() {
res, err := http.Get("https://api.github.com/search/repositories?q=stars:>=10000+language:go&sort=stars&order=desc")
if err != nil {
log.Fatal(err)
}
body, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
}
if res.StatusCode != http.StatusOK {
log.Fatal("Unexpected status code", res.StatusCode)
}
data := JSONData{}
err = json.Unmarshal(body, &data)
if err != nil {
log.Fatal(err)
}
printData(data)
}
func printData(data JSONData) {
log.Printf("Repositories found: %d", data.Count)
const format = "%v\t%v\t%v\t%v\t\n"
tw := new(tabwriter.Writer).Init(os.Stdout, 0, 8, 2, ' ', 0)
fmt.Fprintf(tw, format, "Repository", "Stars", "Created at", "Description")
fmt.Fprintf(tw, format, "----------", "-----", "----------", "----------")
for \_, i := range data.Items {
desc := i.Description
if len(desc) > 50 {
desc = string(desc[:50]) + "..."
}
t, err := time.Parse(time.RFC3339, i.CreatedAt)
if err != nil {
log.Fatal(err)
}
fmt.Fprintf(tw, format, i.FullName, i.StargazersCount, t.Year(), desc)
}
tw.Flush()
}
上面的代碼創建了3個結構體來處理GitHub提供的JSON。JSONData
是主容器,Items
是一個Item
的切片,即存儲庫結構體,在Item內部,Owner
包含存儲庫擁有者的數據。
在得到由http.Get
返回的HTTP響應res
之後,我們使用res.Body
提取內容,並使用ioutil.ReadAll
將其全部讀取到body
中。
在確認res.StatusCode
與http.StatusOK
常數(對應200
)匹配之後,我們使用json.Unmarshal
將JSON解析為我們的JSONData
結構體data
,然後將其傳遞給printData
函數。
在printData
函數內部,我實例化了一個tabwriter.Writer
,然後根據需要依次處理和格式化JSON數據,以生成漂亮的表格佈局: