Blog

golang で JSONPath 的にデータ取り出したいときは @mattn_jp の go-scan が便利

golang で net/http とってきて JSON を parse して所定のキーを取り出すプログラムを書きたかった。 こういう場合、JSONPath とか使って書きたいのだが、JSONPath が完全にサポートされている go のライブラリは見当たらなくて、mattn_jp さんが JSONPath 書こうとして途中でやめた gist がひっかかってくる程度。あとなんか yasuyuky/jsonpath というのもあるのだが、これはいわゆる JSONPath ではない。


JSONPath なくてマジ不便ヤンケ、と思っていたが、mattn_jp さんが go-scan というライブラリを書いていた。

というわけで、go-scan がマジ便利。

https://github.com/mattn/go-scan


以下は metacpan の API にアクセスして、必要な情報を取り出すサンプルである。 マジ便利。 @mattn_jp++

func getRepositoryUrl(module string) (repositoryUrl string, err error) {
	var s string
	url := fmt.Sprintf("http://api.metacpan.org/v0/module/%s?join=release",
		url.QueryEscape(module))
	resp, err := http.Get(url)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	if resp.StatusCode == 200 {
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return "", err
		}
		var v interface{}
		err = json.Unmarshal(body, &v)
		if err != nil {
			return "", err
		}
		err = scan.ScanTree(v, "/distribution", &s)
		if s == "perl" {
			return "", fmt.Errorf("%q is provided by core module", module)
		}
		err = scan.ScanTree(v, "/release/_source/resources/repository/url", &s)
		if err != nil {
			return "", err
		}

		return s, nil
	} else {
		return "", nil
	}
}