Go Cloud Development Kit (Go CDK)を使う理由
2024-09-10
#目次
#はじめに
今回は、Go Cloud Development Kit (以後、Go CDK
)という便利なライブラリを紹介します。
前回、Wire
というDIライブラリを記事で紹介しましたが、Wire
は、実はGo CDK
の一部です。
Go CDK
の使い方などのコードは、この記事では扱いませんので、公式ドキュメントを参照してください。
#Go CDKとは
The Go Cloud Development Kit (Go CDK) is an open source project building libraries and tools to improve the experience of developing for the cloud with Go.
Go CDK provides commonly used, vendor-neutral generic APIs that you can deploy across cloud providers. The idea is to support hybrid cloud deployments while combining on-prem (local) and cloud tools.
出典:https://gocloud.dev/
参考:https://go.dev/blog/go-cloud
Go CDKを使うと、クラウドプロバイダに依存しないコードを書くことができます。
例えば、blob
というインターフェースを使うことで、ストレージサービス(ex. Google Cloud Storage, S3, Azure Blob Storage, Local Storage)へのアクセスをローカル開発環境と各種クラウド環境で同じコードを使うことができます。
これらにより、マルチクラウドアプリケーション、ハイブリッドクラウドアプリケーションを開発することが容易になります。
blob
以外にも、docstore
,pubsub
,runtimevar
,secrets
などの各クラウドプロバイダが一般的に提供しているサービスのインターフェースが提供されています。
#なぜGo CDKを使うのか
いくつかのGo言語のプロジェクトに関わってきた中で、課題は以下の通りです。
- 複数のクラウドプロバイダのAPIを使うためのコードを書く必要がある
- ローカル開発環境とクラウド環境で異なるコードを書く必要がある
1つ目の課題は、いくつかのプロジェクトを関わる中でAWSを使うプロジェクトもあれば、Google Cloudを使うプロジェクトもあり、クラウドプロバイダに依存しないコードを書くことが難しいと感じていました。具体的には、aws-sdk-go
のS3を使うコードと、google.golang.org/api/storage/v1
を使うコードを書く必要があります。ストレージを扱うという点で同じですが、APIが異なるため、コードを書くたびにAPIの違いを意識しながらコードを書く必要があります。
Go CDKを使うことで、クラウドプロバイダに依存しないコードを書くことができるため、この課題を解決できます。
2つ目の課題は、ローカル開発環境とクラウド環境で異なるコードを書く必要があるということです。私のローカル開発環境の要件は、エンドツーエンドのテストができることです。そのため、ローカル開発環境でクラウドプロバイダのAPIを使うためのコードを書く必要があります。Go CDKを使うことで、ローカル開発環境では、たとえば、ローカルファイルシステムを使い、クラウド環境では、Google Cloud Storageを使うコードを書くことができます。これらは、抽象化されているため、コンポーネントの生成時に、どのストレージサービスを使うかを指定するだけで、ローカル開発環境とクラウド環境で異なるコードを書く必要がなくなります。
#DIするためのインターフェースを定義する
Go CDK
では、インターフェースは提供されていませんので、ユニットテストをするためには、インターフェースを定義すると良いでしょう。
例えば、blob
のインターフェースを定義すると以下のようになります。
package blob
import (
"context"
"gocloud.dev/blob"
)
//go:generate mockgen -destination=${GOPACKAGE}mocks/${GOFILE} -package=${GOPACKAGE}mocks -source=$GOFILE
type Attributes = blob.Attributes
type CopyOptions = blob.CopyOptions
type ListOptions = blob.ListOptions
type ReaderOptions = blob.ReaderOptions
type SignedURLOptions = blob.SignedURLOptions
type WriterOptions = blob.WriterOptions
type ListIterator = blob.ListIterator
type ListObject = blob.ListObject
type Reader = blob.Reader
type Writer = blob.Writer
var _ Bucket = (*blob.Bucket)(nil)
type Bucket interface {
As(i interface{}) bool
Attributes(ctx context.Context, key string) (_ *Attributes, err error)
Close() error
Copy(ctx context.Context, dstKey, srcKey string, opts *CopyOptions) (err error)
Delete(ctx context.Context, key string) (err error)
ErrorAs(err error, i interface{}) bool
Exists(ctx context.Context, key string) (bool, error)
IsAccessible(ctx context.Context) (bool, error)
List(opts *ListOptions) *ListIterator
ListPage(ctx context.Context, pageToken []byte, pageSize int, opts *ListOptions) (retval []*ListObject, nextPageToken []byte, err error)
NewRangeReader(ctx context.Context, key string, offset, length int64, opts *ReaderOptions) (_ *Reader, err error)
NewReader(ctx context.Context, key string, opts *ReaderOptions) (*Reader, error)
NewWriter(ctx context.Context, key string, opts *WriterOptions) (_ *Writer, err error)
ReadAll(ctx context.Context, key string) (_ []byte, err error)
SignedURL(ctx context.Context, key string, opts *SignedURLOptions) (string, error)
WriteAll(ctx context.Context, key string, p []byte, opts *WriterOptions) (err error)
}
Go CDKのblob
は、Bucket構造体を提供しますので、その構造体の関数をインターフェースに定義するだけです。
このインターフェースからmockgenを使ってモックを生成することで、ユニットテストを書くことができます。
pubsub
やdocstore
などのインターフェースも同様に定義することができます。
#注意点
Go CDKでは計装については、OpenCensusが採用されています。しかし、OpenCensusは、OpenTelemetryに移行されていますので、計装を実装する場合は、OpenTelemetryを使うことをおすすめします。
こちらのissueではOpenTelemetryに移行することが議論されていますが、まだ移行されていません。OpenTelemetryで計装を実装する場合は、例えば、自分でBucket
インターフェースをWrapして、計装を実装すると良いでしょう。すこし手間がかかりますが。
#まとめ
今回は、Go Cloud Development Kit (Go CDK)について紹介しました。
もし複数のプロダクトで異なるクラウドプロバイダのAPIを使うコードを書いている場合は、Go CDKを使うことで、クラウドプロバイダに依存しないコードを書くことができます。
Go CDKは、Go言語でクラウドアプリケーションを開発する際に便利なライブラリですので、ぜひ使ってみてください。
次回は、Goで環境変数の取り扱いをするライブラリ(godotenv, envconfig)を紹介したいと思います。