Irohabook
0
2278

GolangでGoogle Cloud Storageに画像やファイルをアップロードする(os.Setenvで環境変数GOOGLE APPLICATION CREDENTIALSを設定する)

Go で Google Cloud Storage に画像やファイルをアップロードする方法。アップロードする関数は下のように一つにまとめるとわかりやすい。

import (
    "cloud.google.com/go/storage"
    "context"
    "io"
    "net/http"
    "os"
)

func Upload(r *http.Request) {
    file, fileHeader, err := r.FormFile("image")
    err = os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", "...json")
    bucket := "your-bucket-name"
    objectName := "uploading-filename.png"
    ctx := context.Background()
    client, err := storage.NewClient(ctx)
    writer := client.Bucket(bucket).Object(objectName).NewWriter(ctx)
    writer.ContentType = fileHeader.Header.Get("Content-Type")
    _, err = io.Copy(writer, file)
    err = writer.Close()
}

この関数はエラー処理や一部の file の Close を省略している。上のコードはいくつかのブロックに分けられる。

  • フォームからファイルを受けとる
  • Google Cloud Storage の認証を設定する
  • アップロードする

ファイルを受けとる

まずはファイルを受けとらないといけない。これは

file, fileHeader, err := r.FormFile("image")

が解決する。ちなみに FormFile の引数はフォームの name と同じにする。

<form method="post" enctype="multipart/form-data" action="/">
    <input type="file" name="image" accept="image/*">
    <input type="submit">
</form>

認証

アップロードの難しい部分は Google の認証である。

  • Google Cloud Storage からサービスアカウントキー(JSON ファイル)をダウンロードする
  • JSON ファイルであるサービスアカウントキーを、あなたのプロジェクトのどこかに入れる
  • そのファイルのパスを GOOGLE_APPLICATION_CREDENTIALS という環境変数に設定する

まずはサービスアカウントキーをダウンロードする。

Cloud Storage Client Libraries

のページから「サービス アカウントキーの作成に移動」というページに進み、手順どおりにダウンロードしよう。ファイルは JSON を選択し、ダウンロードしたファイルはあなたのプロジェクトのどこかに入れる。

続いて環境変数を設定する。

os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", "...json")

二番目の引数にサービスアカウントキーのファイルパスを設定する。

アップロード

アップロードは次のように行う。

bucket := "your-bucket-name"
objectName := "uploading-filename.png"

ctx := context.Background()
client, err := storage.NewClient(ctx)

writer := client.Bucket(bucket).Object(objectName).NewWriter(ctx)
writer.ContentType = fileHeader.Header.Get("Content-Type")

_, err = io.Copy(writer, file)

err = writer.Close()

最初に bucket と objectName を設定する。あなたが用意したストレージのバケット名を bucket に入れる。そして objectName にアップロードしたいファイルの名前を入れる。これは Google にアップロードした後のファイル名であって、アップロードする前のファイル名ではない。

context.Background() で ctx という名前のコンテキストをつくり、 storage.NewClient(ctx) で client をつくる。

writer はコードのように設定する。

writer := client.Bucket(bucket).Object(objectName).NewWriter(ctx)
writer.ContentType = fileHeader.Header.Get("Content-Type")

下のように ContentType を具体的に指定するのは良くない。

writer.ContentType = "image/png"

io.Copy(writer, file) で file を writer にコピーする。ここまでは一部のブログ記事が説明するとおりだが、重要なポイントは writer.Close() にある。実は、サーバーにファイルをアップロードする部分はここである。

アップロードできないときに見直すこと

  • フォームに enctype="multipart/form-data" を設定しているか?
  • 認証のサービスアカウントキーをきちんと読みこんでいるか?
  • io.Copy を忘れていないか?
  • writer.Close() を忘れていないか?

ちなみにアップロードするだけなら projectID を設定する必要はない。

次の記事

Go入門