Cloud Storage の使用

Cloud Storage は、ファイル(動画、画像、その他の静的コンテンツなど)を保存または提供する目的で使用できます。

このドキュメントでは、アプリで Google Cloud クライアント ライブラリを使用して、Cloud Storage にデータを格納したり、Cloud Storage からデータを取得したりする方法を説明します。

始める前に

  • App Engine の Go 用「Hello, World!」の説明に従って環境とプロジェクトを設定し、App Engine での Go アプリの構造を理解してください。このドキュメントで説明しているサンプルアプリを実行する際に必要となるため、プロジェクト ID をメモして保存しておきます。

  • 次のコマンドを呼び出して、アプリケーション用の Cloud Storage バケットを作成します。

    gsutil mb gs://[YOUR_BUCKET_NAME]
    
  • バケットを一般公開(読み取り可能)にして、ファイルを提供できるようにします。

    gsutil defacl set public-read gs://[YOUR_BUCKET_NAME]
    

サンプルのダウンロード

リポジトリのクローンを作成するには、次のコマンドを実行します。

go get -d -v github.com/GoogleCloudPlatform/golang-samples/storage
cd $GOPATH/src/github.com/GoogleCloudPlatform/golang-samples/appengine_flexible/storage

プロジェクト構成の編集と依存関係のインストール

app.yamlGCLOUD_STORAGE_BUCKET を設定します。この値は、以前に作成した Cloud Storage バケットの名前です。

# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

runtime: go
env: flex

automatic_scaling:
  min_num_instances: 1

env_variables:
  GCLOUD_STORAGE_BUCKET: your-bucket-name

アプリケーション コード

このサンプル アプリケーションは、Cloud Storage に保存するファイルを指定するように促すウェブページを表示します。ユーザーがファイルを選択して [送信] をクリックすると、アップロード ハンドラが Cloud Storage の NewWriter 関数を使用して、ファイルを Cloud Storage バケットに書き込みます。

このファイルを Cloud Storage から取得するには、バケット名とファイル名を指定する必要があるので注意してください。将来の使用に備えて、これらの値をアプリに保存する必要があります。

// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Sample storage demonstrates use of the cloud.google.com/go/storage package from App Engine flexible environment.
package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"os"

	"cloud.google.com/go/storage"
	"google.golang.org/appengine"
)

var (
	storageClient *storage.Client

	// Set this in app.yaml when running in production.
	bucket = os.Getenv("GCLOUD_STORAGE_BUCKET")
)

func main() {
	ctx := context.Background()

	var err error
	storageClient, err = storage.NewClient(ctx)
	if err != nil {
		log.Fatal(err)
	}

	http.HandleFunc("/", formHandler)
	http.HandleFunc("/upload", uploadHandler)

	appengine.Main()
}

func uploadHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "", http.StatusMethodNotAllowed)
		return
	}

	ctx := appengine.NewContext(r)

	f, fh, err := r.FormFile("file")
	if err != nil {
		msg := fmt.Sprintf("Could not get file: %v", err)
		http.Error(w, msg, http.StatusBadRequest)
		return
	}
	defer f.Close()

	sw := storageClient.Bucket(bucket).Object(fh.Filename).NewWriter(ctx)
	if _, err := io.Copy(sw, f); err != nil {
		msg := fmt.Sprintf("Could not write file: %v", err)
		http.Error(w, msg, http.StatusInternalServerError)
		return
	}

	if err := sw.Close(); err != nil {
		msg := fmt.Sprintf("Could not put file: %v", err)
		http.Error(w, msg, http.StatusInternalServerError)
		return
	}

	u, _ := url.Parse("/" + bucket + "/" + sw.Attrs().Name)

	fmt.Fprintf(w, "Successful! URL: https://storage.googleapis.com%s", u.EscapedPath())
}

func formHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, formHTML)
}

const formHTML = `<!DOCTYPE html>
<html>
  <head>
    <title>Storage</title>
    <meta charset="utf-8">
  </head>
  <body>
    <form method="POST" action="/upload" enctype="multipart/form-data">
      <input type="file" name="file">
      <input type="submit">
    </form>
  </body>
</html>`

詳細情報

Cloud Storage の詳細については、Cloud Storage のドキュメントをご覧ください。