はじめに
最近 golang 触り始めました。まだまだ勝手がわかっていないことが多いです。
今回は、CLI ツールのようなプログラムで、API から取得したデータをで使い回すときの方法について調べてみました。
tl;dr
グローバル変数を使うのが良さそうだと思いました。
想定するケース
aws-sdk-go で、S3 のバケット一覧を取得し、この結果を複数の関数内で何度も利用する場合を考えます。
何度も API からし直すと、そのたびリクエストが走ってしまいます。そのため処理を軽くするために、プログラム内で API から取得したデータを使いまわす方法がないかを調べていました。
サンプルコード
S3 のバケット一覧を取得するサンプルコードです。
package main
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
)
func fetchS3BucketList(profile, region string) {
sess := session.Must(session.NewSessionWithOptions(session.Options{Profile: profile}))
svc := s3.New(sess, aws.NewConfig().WithRegion(region))
result, err := svc.ListBuckets(nil)
if err != nil {
panic(err)
}
fmt.Println(result)
}
func main() {
fetchS3BucketList("SAMPLE_PROFILE_NAME", "ap-northeast-1")
}
グローバル変数を使う
上記くらいの単純なプログラムであれば、プログラム内のグローバル変数として持たせるのが手軽で良いのではないかと思いました。
より規模が大きくなってきたらグローバル変数に持たせた値の影響なども考え始めないといけなくなるので、別案を考えたほうが良さそうです。
コードのイメージ
こんな感じでしょうか。fetchS3BucketList
関数内で取得した API 実行結果を グローバル変数の bucketList
に保持して、main
関数内で使えるようにしています。
package main
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
)
var bucketList s3.ListBucketsOutput
func fetchS3BucketList(profile, region string) {
sess := session.Must(session.NewSessionWithOptions(session.Options{Profile: profile}))
svc := s3.New(sess, aws.NewConfig().WithRegion(region))
result, err := svc.ListBuckets(nil)
if err != nil {
panic(err)
}
bucketList = *result
}
func main() {
fetchS3BucketList("SAMPLE_PROFILE_NAME", "ap-northeast-1")
fmt.Println(bucketList)
}
おわりに
簡単な例だったのですが、グローバル変数以外に関数間で値を使い回す方法があれば教えていただけるとありがたいです。