LoginSignup
2
0

More than 1 year has passed since last update.

google-cloud-go の使ってみた操作まとめ

Posted at

前から Google Cloud Storage には興味があったのでラーメンの写真を記録するサービスを作るのに使ってみました。機能ごとにもリンクを貼りますが、ひとまず公式ドキュメントとリポジトリは以下になります。

実行環境

go: v1.18
cloud.google.com/go/storage: v1.22.0

※ 全体を通してエラーハンドリングは省略しています。

事前準備:クライアントの作成

クライアントの作成に使用するため、事前に GCP のアカウント作成と鍵ファイルをダウンロードしておきます。

今回はダウンロードした鍵ファイルを引数にとり [WithCredentialsFile] を使用します。(https://pkg.go.dev/google.golang.org/api/option#WithCredentialsFile)

// これ以降のコードは func main 内のみ記載します
package main

import (
	"context"
	"cloud.google.com/go/storage"
)

func main() {
	ctx := context.Background()
    client, _ := storage.NewClient(ctx, option.WithCredentialsFile("./key.json"))
}

公式ドキュメントには

The client will use your default application credentials. Clients should be reused instead of created as needed. The methods of Client are safe for concurrent use by multiple goroutines.
クライアントは必要に応じて作成するのではなく、再利用することが望ましいです。Clientのメソッドは、複数のゴルーチンによる同時使用にも安全です。

とあるため、本記事では都合上毎度定義し直してますが どこか一箇所で定義して使い回すのがよさそうです。
複数のゴルーチンによる同時使用にも安全です。 とあるのは context を引数としてるからですかね。あまり context を理解していない

バケットの作成

バケットの作成は BucketHandle.Create を使用します。
bucket-name は作成したいバケット名で、 my-project はバケットを作りたいプロジェクト名(実在するもの)です。

ctx := context.Background()
client, _ := storage.NewClient(ctx)	
client.Bucket("bucket-name").Create(ctx, "my-project", nil)

余談ですが、 client.Project("my-project").CreateBucket(ctx, "bucket-name") みたいな書き方の方が個人的にはしっくりくるので、できそうでしたら教えてください🙇‍♂️

ファイルのアップロード

ファイルアップロード(オブジェクトの作成)には BucketHandle.Create を使用します。

// 適当なファイルを作成
f, _ := os.Create("sample.txt")
// file-name はオブジェクトに付けたい名前
writer := user.Client.Bucket("bucket-name").Object("file-name").NewWriter(ctx)
io.Copy(writer, e.File)
writer.Close()

file-namefolder/file.txt のようにパス構造にする事で階層を持ってアップロードする事ができます。

※1 file-name をパス構造として階層にすることはあまりお勧めしません。
詳しくはディレクトリトラバーサルと検索ください。

※2 オブジェクトの更新にObjectHandle.Update がありましたが、BucketHandle.Create が UPSERT (同じ file-name のオブジェクトなければ作成、あれば更新)のような役割をしていたため今回は使用してません。個人開発なのでオブジェクトのバージョンとかも気にする必要はありませんし。
パフォーマンスなどで明らかに優れる点がありましたら教えてください。

オブジェクトの取得

オブジェクトの取得には ObjectHandle.NewReader を使用します。

obj := user.Client.Bucket("bucket-name").Object("file-name")
rc, _ := obj.NewReader(ctx)
buf := new(bytes.Buffer)
io.Copy(buf, rc);

特定の条件のオブジェクトの情報を取得したい場合は BucketHandle.Objects を使用するようです。

ctx := context.Background()
client, _ := storage.NewClient(ctx)
it := client.Bucket("my-bucket").Objects(ctx, nil)

BucketHandle.Objects の第二引数へは Query を渡す事ができ、取得するオブジェクトを絞り込めるようです。(nil でバケット配下を全て取得します)
たとえば folder 配下のオブジェクトの情報(ObjectIterator)のみを取得する場合は以下のようになります。

ctx := context.Background()
client, _ := storage.NewClient(ctx)
query := &storage.Query{
    StartOffset: "folder/"
}
it := client.Bucket("my-bucket").Objects(ctx, query)

この ObjectIterator からそれぞれのオブジェクト名(ObjectAttrs.name を取得して、ObjectHandle.NewReaderを取得します。

(より良いやり方ありましたら教えていただければと思います🙇‍♂️)

以下の公式ドキュメントも参考にいただければと思います。

オブジェクトの削除

オブジェクトの削除には BucketHandle.Delete を使用します。

ctx := context.Background()
client, _ := storage.NewClient(ctx)
client.Bucket("my-bucket").Delete(ctx)

最後に

今回は基本的な操作に関してのみ記載いたしました。今後気になる機能があったら追記等々行っていきたいと思います。
最後までお付き合いいただきありがとうございました🙇‍♂️

参考リンク

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0