goのCloud FunctionsがBetaじゃなくなったので、使ってみた 一般的にはhttpよりもGCSとかPUB/SUB周りで使用するイメージですが、今回はhttpでサンプルを作っていきます。(httpならGAEでも良かったけど。。。)
まずはチュートリアル
※gcloudの設定周りはできている前提
以下のファイル作成
■ hello_world.go
package helloworld import ( "fmt" "net/http" ) // HelloGet is an HTTP Cloud Function. func HelloGet(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello, World!") }
で、コマンド実行
$gcloud functions deploy HelloGet --runtime go111 --trigger-http
で確認
$curl https://us-central1-プロジェクトID.cloudfunctions.net/HelloGet Hello, World!
デプロイできました
FireStoreを使ってみる
Firebaseを導入
$go get firebase.google.com/go
Firebaseのクライアントを取得
- Firebaseのクライアントはサービスアカウントの鍵を生成して認証
■firestore.go
package app import ( "context" "cloud.google.com/go/firestore" firebase "firebase.google.com/go" "google.golang.org/api/option" ) func getFireBaseClient(ctx context.Context) (*firestore.Client, error) { opt := option.WithCredentialsFile("serviceAccountKey.json") app, err := firebase.NewApp(ctx, nil, opt) if err != nil { return nil, err } return app.Firestore(ctx) }
データを保存
Collectionを「results」に設定 ドキュメントにUUIDを設定して、そこに「item」を設定する
package app import ( "context" "encoding/json" "net/http" "time" "github.com/rs/xid" ) func SaveItem(w http.ResponseWriter, r *http.Request) { ctx := context.Background() client, err := getFireBaseClient(ctx) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } jst, err := time.LoadLocation("Asia/Tokyo") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } guid := xid.New() item := Item{ Status: "OK", Day: time.Now().In(jst).Format("2006-01-02"), } _, err = client.Collection("results").Doc(guid.String()).Set(ctx, item) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") res, err := json.Marshal(item) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(res) }
データを取得
Collectionを「results」に設定してWhereで「day」が今日の日付になっているデータを取得
package app import ( "context" "encoding/json" "net/http" "time" ) func GetItem(w http.ResponseWriter, r *http.Request) { ctx := context.Background() client, err := getFireBaseClient(ctx) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } jst, err := time.LoadLocation("Asia/Tokyo") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } day := time.Now().In(jst).Format("2006-01-02") matchItem := client.Collection("results").Where("day", "==", day).Documents(ctx) docs, err := matchItem.GetAll() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } data := []interface{}{} for _, doc := range docs { data = append(data, doc.Data()) } w.Header().Set("Content-Type", "application/json") res, err := json.Marshal(data) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(res) }
デプロイ
$gcloud functions deploy SaveItem --runtime go111 --trigger-http $gcloud functions deploy GetItem --runtime go111 --trigger-http
これで完成
github
その内、自分でも使いそうなので忘れないようにリポジトリを作っておきました。
最後
GAEで良いような気もするけど、たまにバージョンを作りすぎてデプロイできなくなるから、実験用のAPIはCloud Functionsでも良いかも