【Golang,go-ini】OpenWeatherAPIを利用して天気を取得する

2月 12, 2022

どもです。早く春服の季節がやってきて欲しい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-


↓本日のオススメ教材

Golang

Posted by CY