#使用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.StatusCodehttp.StatusOK常數(對應200)匹配之後,我們使用json.Unmarshal將JSON解析為我們的JSONData結構體data,然後將其傳遞給printData函數。 在printData函數內部,我實例化了一個tabwriter.Writer,然後根據需要依次處理和格式化JSON數據,以生成漂亮的表格佈局: