Git.io から短縮 URL を取得するコード
(初出: Git.io 短縮 URL を golang コードで取得してみる - Qiita)
Git.io で短縮 URL が取得できるらしい
これを読んでたら後ろの方に Git.io の話が出ていた。 このサイトで短縮 URL を生成できるらしい。
API が curl で掲載されていて,例えば私の https://github.com/spiegel-im-spiegel なら
$ curl -i "https://git.io" -F "url=https://github.com/spiegel-im-spiegel"
HTTP/1.1 201 Created
Server: Cowboy
Connection: keep-alive
Date: Sat, 08 Aug 2015 02:42:16 GMT
Status: 201 Created
Content-Type: text/html;charset=utf-8
Location: http://git.io/vOj52
Content-Length: 37
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Runtime: 0.210952
X-Node: 871d903e-a8e0-46ff-a96f-ef424385e5ed
X-Revision: b1d9ce07ccb700fc90398edafd397beb8d3bd772
Via: 1.1 vegur
https://github.com/spiegel-im-spiegel
てな感じで,ヘッダの Location 要素に短縮 URL が返ってくる仕組みらしい。 って,これって curl で書けるんなら Go 言語で表現できるんじゃね?
cURL as DSL
- cURL as DSL — cURL as DSL 1.0 documentation
- Shibu’s Diary: cURL as DSLとは何だったのか。あるいは細かすぎて伝わらないcURL as DSL。
cURL as DSL とは curl の構文を任意のコード1 に変換してくれるもので,どういうことかというと「Web API は curl で表現すればいいんじゃね?」ということらしい。
さっそく curl を Go 言語に変換してみる
では早速,上述の curl コマンドを cURL as DSL を使って Go 言語に変換してみる(ただし -i
オプションは付けない)。
結果はこんな感じ。
package main
import (
"bytes"
"io/ioutil"
"log"
"mime/multipart"
"net/http"
)
func main() {
var buffer bytes.Buffer
writer := multipart.NewWriter(&buffer)
writer.WriteField("url", "https://github.com/spiegel-im-spiegel")
writer.Close()
resp, err := http.Post("https://git.io", "multipart/form-data; boundary="+writer.Boundary(), &buffer)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
log.Print(string(body))
}
出力のみちょっと弄って
package main
import (
"bytes"
"io/ioutil"
"log"
"mime/multipart"
"net/http"
)
func main() {
var buffer bytes.Buffer
writer := multipart.NewWriter(&buffer)
writer.WriteField("url", "https://github.com/spiegel-im-spiegel")
writer.Close()
resp, err := http.Post("https://git.io", "multipart/form-data; boundary="+writer.Boundary(), &buffer)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
log.Println(" Status: ", resp.Header.Get("Status"))
log.Println("Location: ", resp.Header.Get("Location"))
log.Println(" Body: ", string(body))
}
として実行すると
C:>go run gitio.go
2015/08/08 12:00:00 Status: 201 Created
2015/08/08 12:00:00 Location: http://git.io/vOj52
2015/08/08 12:00:00 Body: https://github.com/spiegel-im-spiegel
となり,めでたく短縮 URL が取得できた。
ちなみに最初の curl コマンドの -F
を -d
に替えて cURL as DSL にかけると2
package main
import (
"io/ioutil"
"log"
"net/http"
"net/url"
)
func main() {
values := url.Values{
"url": {"https://github.com/spiegel-im-spiegel"},
}
resp, err := http.PostForm("https://git.io", values)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
log.Print(string(body))
}
のように変換される。
http
.Post()
関数から http
.PostForm()
関数に替わってかなりコードがすっきりした。
今回のような単純な request ならこちらの方がいいだろう。
ついでにパッケージも作ってみた
これを称して「他人の褌で相撲を取る」という3。 なるほど。 こうやって API を実装していくんだね。
ブックマーク
- よく使うcurlコマンドのオプションまとめ(12個) - Qiita
- curlコマンドをPythonやnode.jsのコードに変換する方法 - Qiita : Python への変換はこちらのサービスのほうが簡潔なコードを吐いてくれるらしい