🌟

URI からデータを取ってくるだけの簡単なお仕事

2021/01/13に公開

今回も仕事の合間の息抜きを!

自分で作って使ってるツール群について RESTful API なデータを取ってくるコードをあちこちで個別に書いていて,そろそろコピペにも飽きてきたので,「取ってくる」機能だけに特化した独立パッケージとして切り出すことにした。

https://github.com/spiegel-im-spiegel/fetch

まずは GET にのみ注力する。このパッケージを使って,たとえばこんな感じに書ける。

sample.go
// +build run

package main

import (
    "context"
    "fmt"
    "io"
    "net/http"
    "os"

    "github.com/spiegel-im-spiegel/fetch"
)

func main() {
    githubUser := "spiegel-im-spiegel"
    u, err := fetch.URL("https://api.github.com/users/" + githubUser + "/gpg_keys")
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        return
    }
    resp, err := fetch.New(fetch.WithHTTPClient(&http.Client{})).
        Get(
            u,
            fetch.WithContext(context.Background()),
            fetch.WithRequestHeaderSet("Accept", "application/vnd.github.v3+json"),
        )
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        return
    }
    defer resp.Close()
    if _, err := io.Copy(os.Stdout, resp.Body()); err != nil {
        fmt.Fprintln(os.Stderr, err)
    }
}

これを使って

$ go run sample.go | jq -r '.[]|select(.key_id=="B4DA3BAE7E20B81C")|.raw_key'
-----BEGIN PGP PUBLIC KEY BLOCK-----

mQSuBFF8+hcRDAClgJHjXcpxJhhx2aaxQEF/V6ds8DL358hk2TRXmpcpwBmjSCB4
cW/soISF6vzPQgWNvZjaPwWfrwWRjMsfk/9XfDtibvIgqShtS5Nc/p6/wxOMHh6x
...

ほら, GitHub サイトから OpenPGP 公開鍵が取り出せた。

(何をやってるかは以前に書いた「GitHub に登録した OpenPGP 公開鍵を取り出す」を参照のこと)

OAuth みたいな認証機能があるわけじゃないし,ニッチ過ぎて汎用パッケージとしては使えないと思うけど,net/http パッケージを使う上でありがちなバグや脆弱性が出にくいように書いてるつもりではある。

cURL as DSL

上のサンプル・コードは以下の curl コマンドラインとほぼ同等である。

$ curl "https://api.github.com/users/spiegel-im-spiegel/gpg_keys" -H "Accept: application/vnd.github.v3+json"

というより,まず「API 仕様」としての curl コマンド例があって,それに沿うようにコードを書くことが多い。

実は,その名もずばり “cURL as DSL” というツールというかサービスがあって,私は昔からお世話になっている。 “cURL as DSL” は curl のコマンドラインから Go, Python, node.js, Java, PHP, Vim script などのコードに変換してくれる。

もっとも “cURL as DSL” 自体はもうメンテナンスされてないようで,同様のサービスとして

https://curl.trillworks.com/

を勧めている。こちらは更に多くの言語に対応している。

この手のツールを使うようになったきっかけは2015年に “cURL as DSL” を公開された渋川よしきさんの以下の記事で

http://blog.shibu.jp/article/115602749.html

特に

このツールを発想したきっかけが、Google Chromeの開発者ツールの「Copy as cURL」というメニューです。cURL形式でコピーできるなら、cURLコマンドは多くのユーザが気軽に作れます。コミュニケーション手段になると思いました。例え冗長でも、自動生成できるというのは、非プログラマにとってはとてもありがたい選択肢になります。ExcelのVBAだって、FlashのJSFLだって、プログラマじゃない人がたくさん使っていますからね。

また、PythonやらRubyやらnode.jsを使ったことがある人は、インタラクティブモードとかirbとかREPLといった環境の便利さはよく理解されていると思います。cURLが広まって、みんながウェブのドキュメントにcURLの擬似コードを書いてくれるようになれば、cURLはHTTP界におけるREPLになる可能性もあると思っています。

という部分は当時「激しく同意」してしまった。

ぶっちゃけ curl コマンドライン例と利用可能なパラメータの一覧表があればコード化できるもんね。 PA-APIv5 のクライアント側パッケージを作ったときも Amazon さんが curl のサンプルコードを公開してくれたおかげで理解が容易だった面は否めない(あとは PHP のコード。 Java はコード詳細が隠蔽されていてワケが分からんかったw)。

というわけで,これから RESTful API 仕様を一般公開される場合は,是非とも curl で書いてください 🙇 いや,時代は GraphQL だろうけど(笑)

関連リンク

参考図書

https://www.amazon.co.jp/dp/4908686033

https://www.amazon.co.jp/dp/4873119030

GitHubで編集を提案

Discussion