まさひちの道具箱

趣味の話から技術・仕事まであらゆることをたれ流していきます

Goでhttpリクエストを送る

特にこれといって動機はないのですが、Go言語でバッチ処理的にAPIを叩く処理を実装してみたのでメモ。

なにもGoでやらなくてもPHPだって、Pythonだって、なんならshellだってできるのですが、 なんとなくGoってさわったことないし、やってみるか的な感覚です。 特にすごいことでもないし、他の方の記事なんかで散々書かれているのでわざわざ新しくまとめる意味もないんですが。

Go環境構築

まずは環境を整えることから。

https://golang.org/dl/から最新バージョンのGoをダウンロードします。

sudo wget https://storage.googleapis.com/golang/go1.10.linux-amd64.tar.gz

うまくいったら、解凍

sudo tar -C /usr/local -xzf go1.10.linux-amd64.tar.gz

/usr/localは別に違っててもいいです。好きなところを指定してください。

次にgoコマンドを認識できるようにPATHを通します。

$ vim ~/.bash_profile
// 以下を追記
export PATH=$PATH:/usr/local/go/bin

// 認識させる
$ source ~/.bash_profile

うまく通って入れば

$ go env

で、goの環境設定が表示されるはずです。

GOARCH="arm"
GOBIN=""
GOEXE=""
GOHOSTARCH="arm"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/user/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_arm"
GCCGO="gccgo"
GOARM="6"
CC="gcc"
GOGCCFLAGS="-fPIC -marm -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build984502013=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"

httpリクエストの実装

適当な場所にmain.goを作って実装を書いていきます。

何か叩く先があると楽しいので、今回はYahoo!デベロッパーネットワークで公開されているYOLP(地図サービス)の郵便番号検索APIを叩いてみます。

YDNはアプリケーション名を登録するとAPIを叩くためのappidが発行されるので、簡単に叩けます。

http.Client

Goでhttpリクエストを送信する方法はいくつかあるようですが、

一番カスタマイズできるやつを覚えておけば問題ないだろう(大は小を兼ねる的な)ということで、http.Clientを使います。

importにnet/httpを加えてください。

  • リクエストクエリの作成
request , err := http.NewRequest("GET", URL, nil)

のようにするとGETリクエスト用のhttp.Requestとエラーを返します。 第三引数はパラメータですが、自分の場合は

// valuesにリクエストパラメータを設定
values := url.Values{}
values.Add("appid", string(appid)) // YDNのappid
values.Add("query", "xxx-yyyy") // 検索する郵便番号
values.Add("output", "json") // レスポンスの形式:今回はJSON

reqest.URL.RawQuery = values.Encode()

として、後から設定する派です。

client := new(http.Client)

でhttp.Clientを作ってから

resp, _ := client.Do(request)
defer resp.Body.Close()

でhttpリクエストを送信します。 resp.Bodyにレスポンスの実体があるので

body, err := ioutil.ReadAll(resp.Body)

はい、レスポンス取得できました。

エンコードがおかしかったりして文字化けしてたりするので、次回はそこらへんを直していきましょうか。

まとめ

今回作ったものの全容はこんな感じ

package main

import (
    "fmt"
    "net/http"
    "net/url"
    "io/ioutil"
)

func main() {
    // サンプルとしてYOLPの郵便番号検索APIを叩く
    values := url.Values{}
    values.Add("appid", <appid>)
    values.Add("query", <郵便番号>)
    values.Add("output", "json")

 url := "https://map.yahooapis.jp/search/zip/V1/zipCodeSearch"

    // http.Getでリクエストを作る
    request, err := http.NewRequest("GET",url,nil)
    if err != nil {
        fmt.Println(err)
        return
    }
    request.URL.RawQuery = values.Encode()

    // リクエスト送信
    client := new(http.Client)
    resp, _ := client.Do(request)
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println(string(body))