【Golang,go-ini】OpenWeatherAPIを利用して天気を取得する
どもです。早く春服の季節がやってきて欲しいsaisaiです。
最近完全在宅勤務の影響か引きこもりに拍車がかかり、その日の天気を知ることなく1日を終えることがあります。
なので今回はGolangとOpenWeatherMapのAPIを利用して天気を取得し、ターミナルで確認できるようにしてみました!
「何番煎じなんだ!」なネタですが"configファイルを利用したクレデンシャル情報の管理・出力"の練習もしたかったのでAPIキーを必要とするこのトピックを選びました。
完成形の挙動は以下の通りです。
それでは、早速やっていきましょう。
configファイルの作成
今回天気を取得するために"OpenWeatherAPI"というAPIを利用します。このAPIを取得するにはOpenWeatherMapアカウントを作成し、事前にAPIキーを取得しておく必要があります。キーを取得される場合は以下のサイトをご参照ください。
世界の天気API「OpenWeatherMap」の無料APIキー発行・取得、リクエスト方法
APIキーを取得したら、いよいよconfigファイルを作成・設定していきます。
プロジェクトのルートディレクトリに"config.ini"という名前のファイルを作成し、以下のように書き込みます。
[API_FORCAST_KEY]
api_key = 取得したAPIキーの値
これでAPIキーの情報の置き場所を作成し、キー情報を格納しておくことができました!
go-iniの設定
続いてgo-iniを使用してconfigファイルを読み込み、キー情報をプログラム側で取得するGoファイルを作成します。
わかりやすいようにconfigパッケージ(ディレクトリ)を作成し、今回は"config.go"というファイル名で作成していきます。事前に"go get github.com/go-ini/ini"でパッケージを取得しておいてください。
package config
import (
"log"
"github.com/go-ini/ini"
)
type Configlist struct {
ApiKey string
}
//読み込んだAPIキー情報を格納する構造体
var Config Configlist
//構造体を変数に代入
func init() {
cfg, err := ini.Load("config.ini") //config.ini内の情報を読み込んで変数に代入
if err != nil {
log.Fatalf("failed to read file\n", err)
}
//エラーハンドリング
Config = Configlist{
ApiKey: cfg.Section("API_FORCAST_KEY").Key("api_key").String(),
//構造体のApiKeyフィールドにAPI_FORCAST_KEYセクションのapi_keyの値(APIキー)を入れる
}
}
これでAPIキーの情報を持つパブリックな変数"Config"が爆誕しました。
天気を取得する
それではいよいよ天気を取得するmain関数を作成しましょう。ルートディレクトリにGoファイル"main.go"を作成します。今回使用するコードは以下の記事を参考にさせていただきました。
Goでopenweatherapiを使って東京の天気を取得する
僕は関西住まいなので、今回は大阪の天気を取得してみようと思います。
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"time"
"weatherProject/config"
)
type OpenWeatherMapAPIResponse struct {
Weather []Weather `json:"weather"`
Dt int64 `json:"dt"`
}
//OpenWeatherAPIが返す情報の内、時刻と天気の情報を格納する構造体
type Weather struct {
Main string `json:"main"`
}
//天気の情報の中のMainセクションの情報を格納する構造体
func main() {
token := config.Config.ApiKey //APIキーを指定(後述)
city := "Osaka,jp" //場所を指定
endPoint := "https://api.openweathermap.org/data/2.5/weather" //APIのエンドポイントを指定(このURLでOK)
values := url.Values{} //urlにさらに値を追加する変数を指定
values.Set("q", city) //変数cityの値を追加
values.Set("APPID", token) //変数tokenの値を追加
res, err := http.Get(endPoint + "?" + values.Encode()) //情報を追加したエンドポイント(URL)にGet
if err != nil {
panic(err)
}
defer res.Body.Close() //読み込んだBodyを後から閉じる
bytes, err := ioutil.ReadAll(res.Body) //getで得たBodyを読み込んで変数に代入
if err != nil {
panic(err)
}
var apiRes OpenWeatherMapAPIResponse 変数apiResに構造体を代入
if err := json.Unmarshal(bytes, &apiRes); err != nil {
panic(err)
}
//json形式でBodyの情報を構造体(OpenWeatherMapAPIResponse)に格納し、jsonから構造体の形に整形(json.Unmarshal)
fmt.Printf("場所: %v\n", city)
fmt.Printf("時刻: %s\n", time.Unix(apiRes.Dt, 0))
fmt.Printf("天気: %s\n", apiRes.Weather[0].Main)
//それぞれ出力
}
要素が多すぎるのでコードにコメントを書きまくりました(笑)
ちなみにAPIキーを呼び出しているのが
token := config.Config.ApiKey
の部分になりますが、これをもっとわかりやすく解説すると以下のようになります。
configパッケージ内の.変数Configの.ApiKeyの値
ということでconfig.iniに代入されているAPIキー情報を変数"token"に代入しているということがわかりましたね。
ひとこと
今回はconfig.iniでクレデンシャル情報を管理しつつ、天気を取得するコードを書いてみました。
プログラムに直接クレデンシャル情報を書くのはご法度です。この情報さえあればAPIを借りていろいろな悪事を働くことができるからです。
クレデンシャル情報を管理する方法は他にもたくさんありますが、情報漏洩が内容最新の注意を払いたいところですね。特に最近なにかと話題のGithubとか…。
ここまで読んでいただきありがとうございました!
-saisai-
↓本日のオススメ教材