使用Go从GitHub获取存储库列表

在本文中,我将仅使用Go来询问有关公共存储库的GitHub API信息。net/httpstdlib软件包,没有任何其他库。

GitHub有一个不错的公共API,称为Search,您可以在以下位置进行检查https://developer.github.com/v3/search/#search-repositories

我特别感兴趣获得超过1万颗星的Go存储库在这个时间点。

我们可以向其传递查询以获取我们想要的确切信息。查看Search API文档,我们将必须发出HTTP GET请求以https://api.github.com/search/repositories传递查询?q=stars:>=10000+language:go&sort=stars&order=desc:为我提供超过1万颗星的存储库,使用Go语言,请按星数对它们进行排序。

最简单的代码段:我们使用http.Getnet/http我们阅读了使用返回的所有内容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”)

<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
	<span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Fatal</span>(<span style="color:#a6e22e">err</span>)
}

<span style="color:#a6e22e">body</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">ioutil</span>.<span style="color:#a6e22e">ReadAll</span>(<span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">Body</span>)
<span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">Body</span>.<span style="color:#a6e22e">Close</span>()
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
	<span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Fatal</span>(<span style="color:#a6e22e">err</span>)
}
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">StatusCode</span> <span style="color:#f92672">!=</span> <span style="color:#ae81ff">200</span> {
	<span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Fatal</span>(<span style="color:#e6db74">"Unexpected status code"</span>, <span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">StatusCode</span>)
}

<span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">"Body: %s\n"</span>, <span style="color:#a6e22e">body</span>)

}

它是可读性不强, 如你看到的。您可以粘贴使用的内容在线格式化程序了解实际结构。

现在让我们处理JSON并从中生成一个漂亮的表。

如果您不熟悉JSON主题,请参阅有关以下内容的初步指南:如何使用Go处理JSON

package main

import ( “encoding/json” “fmt” “io/ioutil” “log” “net/http” “os” “text/tabwriter” “time” )

// Owner is the repository owner type Owner struct { Login string }

// Item is the single repository data structure 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 contains the GitHub API response 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,存储库结构和内部项目,Owner包含存储库所有者数据。

给出HTTP响应res由...返回http.Get我们使用提取身体res.Body我们读了所有bodyioutil.ReadAll

检查后res.StatusCode符合http.StatusOK常数(对应于200),我们使用来解组JSONjson.Unmarshal进入我们的JSONData结构data,然后将其传递给我们进行打印printData结构。

里面printData我实例化一个tabwriter.Writer,然后相应地处理和格式化JSON数据,以输出漂亮的表布局:


更多教程: