当ブログ人気記事!
転職体験談
Laravelで学ぶWebアプリ開発
誰でも作れるチャットアプリ
未経験への勧め

【Go×Google Cloud Functions×Cloud SQL】サーバーレスAPI開発〜デプロイ

プログラミング

GoのAPIをサクッと本番環境にあげたい!
GoogleCloudを使ってみたい!

本記事はこういった悩みに対しての記事です!

この記事を書いている僕(@Shoot58153748)は、
2020年5月現在メガベンチャーの社内スタートアップの部署で
エンジニア(2年目突入)をしており、

プログラミング未経験からメガベンチャーへの転職を成功させた経験・ノウハウ
Webエンジニアになってから学んだこと

をブログにまとめています。

今回は、「GoogleCloud」というクラウドサービスを使って
サクッとGoのAPIを作成〜デプロイします。

そろそろ自分のコードを世に公開したい!というあなたはぜひ参考にしてください。

スポンサーリンク

サーバーレス開発とは


普通ソースコードを世に公開するためには、

Linuxインストールして、
必要なパッケージ・ミドルウェアインストールして、
ログ管理、リソース管理して、、、

などのインフラの知識が必要です。

サーバーレス開発は、開発者がインフラを意識することなく、コードの記述のみに専念できる、新しいアプリケーション開発です!


従来のコンピューティングに比べ、
サーバー管理不要、自動スケーリング、使用したリソースのみの支払い

などの利点が多くあります。

サービス的にはAmazonのLambda、GoogleのCloud Functions
など、クラウドサービスを使って開発していきます。

サーバーレス開発を学ぶことで会社での業務に活きる!
とは言い難いですが、

一人、または少人数で新たなサービスを早く作ってリリースしたい場合、
インフラの知識は全てAmazonやGoogleが請け負ってくれるので
非常に良いオプションになるはず!

今後サーバーレス開発はさらに増えてくるはずです。

今回は、GoogleのCloud Functionsを使います。

GoogleCloudによるサーバーレスAPI開発手順

Google Cloudでプロジェクト作成

※初めての方は1年間の無料トライアルへの登録を済ませましょう

様々なGoogle Cloud Platformのサービスを使うためには、
プラットフォーム上でプロジェクトを作成する必要があります。

Cloud Console のプロジェクト セレクタページで、Cloud プロジェクトを選択または作成します。


任意のプロジェクト名を入力して作成をクリックしましょう。

作成できたら、課金の有効化をします。

作成したプロジェクトのダッシュボードへ行き、
Consoleのナビゲーションメニューのお支払いを選択

請求先アカウントをリンクをクリックして課金を有効化します。
※有効化しないとCloud Functionsは使えません

以上でプロジェクトの準備は整いました!

Google Cloud SDKをインストール

続いて、ローカルで開発するためにGoogle Cloud SDKをあなたのパソコンにインストールします。

公式ドキュメントのこちらのリンクからSDKをダウンロードします。

任意のところにダウンロードできたら解凍し、
解凍したディレクトリ(google-cloud-sdk)内の以下のスクリプトを実行し、パスを通します。

./google-cloud-sdk/install.sh

SDKの設定を初期化(Google Account認証→プロジェクト選択)して、

初期化が終わったら、プロジェクト情報を確認しましょう。
確認できたら開発の準備が整いました。

gcloud init

// 初期化終了後、作成したプロジェクト情報を確認
gcloud projects describe shootoku-20200502

Google Cloud SQL(MySQL)のインスタンス作成

Cloud FunctionsからCloud SQL(MySQL)に接続するため、
Cloud SQLのインスタンスを作成します。
ナビゲーションメニューのCloudSQLを選択>インスタンスを作成
をクリック

そしてRDBを選択

設定してインスタンスを作成

作成したら、コマンドで確認

INSTANCE_CONNECTION_NAMEなどの情報は接続の時使うのでメモしておきましょう。

gcloud sql instances describe shootoku-mysql


最後にDBを作成します。

ローカルのPCからCloudSQLにアクセスするには、プロキシを噛ませます。

// プロキシ設定のダウンロード
curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64
// 実行権限付与
chmod +x cloud_sql_proxy
// プロキシ立ち上げ
cloud_sql_proxy -instances=[INSTANCE_CONNECTION_NAME]=tcp:3306
// DB接続
mysql -u root -p --host 127.0.0.1 --port 3306

パスワード認証を通ったらローカルからインスタンスのDBにアクセスできます。
最後にDBを作成します。

CREATE DATABASE [YOUR_DATABASE_NAME];

以上でDBの準備は整いました!

Google Cloud Functions用API開発

ディレクトリの構成

以下のコマンドでgo.modを作成できます。
依存パッケージ(github.com/go-sql-driver/mysqlのような)を使う場合は、必要です。

go mod init

// IDEでパッケージ自動インストール環境がない場合
go get github.com/go-sql-driver/mysql

event.go

package events

import (
	"database/sql"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"

	_ "github.com/go-sql-driver/mysql"
)

var db *sql.DB

// EventHandler is an HTTP Cloud Function.
func EventHandler(w http.ResponseWriter, r *http.Request) {

	if r.Method == http.MethodGet {
		var err error
		db, err = initSocketConnectionPool()
		if err != nil {
			log.Printf("db connection error \n")
			fmt.Fprintf(w, err.Error())
			return
		}
		defer db.Close()
		log.Printf("db connection success \n")
	}
	if r.Method == http.MethodPost {
		io.WriteString(w, "This is a post request")
	}
}

// mustGetEnv is a helper function for getting environment variables.
// Displays a warning if the environment variable is not set.
func mustGetenv(k string) string {
	v := os.Getenv(k)
	if v == "" {
		log.Printf("Warning: %s environment variable not set.\n", k)
	}
	return v
}

// initSocketConnectionPool initializes a Unix socket connection pool for
// a Cloud SQL instance of MySQL.
func initSocketConnectionPool() (*sql.DB, error) {
	// [START cloud_sql_mysql_databasesql_create_socket]
	var (
		dbUser                 = mustGetenv("DB_USER")
		dbPwd                  = mustGetenv("DB_PASS")
		instanceConnectionName = mustGetenv("INSTANCE_CONNECTION_NAME")
		dbName                 = mustGetenv("DB_NAME")
	)

	var dbURI string
	dbURI = fmt.Sprintf("%s:%s@unix(/cloudsql/%s)/%s", dbUser, dbPwd, instanceConnectionName, dbName)

	// dbPool is the pool of database connections.
	dbPool, err := sql.Open("mysql", dbURI)
	if err != nil {
		return nil, fmt.Errorf("sql.Open: %v", err)
	}

	// [START_EXCLUDE]
	configureConnectionPool(dbPool)
	// [END_EXCLUDE]

	return dbPool, nil
	// [END cloud_sql_mysql_databasesql_create_socket]
}

// configureConnectionPool sets database connection pool properties.
// For more information, see https://golang.org/pkg/database/sql
func configureConnectionPool(dbPool *sql.DB) {
	// [START cloud_sql_mysql_databasesql_limit]

	// Set maximum number of connections in idle connection pool.
	dbPool.SetMaxIdleConns(5)

	// Set maximum number of open connections to the database.
	dbPool.SetMaxOpenConns(7)

	// [END cloud_sql_mysql_databasesql_limit]

	// [START cloud_sql_mysql_databasesql_lifetime]

	// Set Maximum time (in seconds) that a connection can remain open.
	dbPool.SetConnMaxLifetime(1800)

	// [END cloud_sql_mysql_databasesql_lifetime]
}

EventHandlerがHTTPリクエスト時に実行され、
initSocketConnectionPoolで接続プール設定します。

GETリクエストに対して、
接続に成功したらdb connection successというログを出力するものです。

.gcloudignore

go.sum

cloud functionsへのデプロイに含めたくない場合は、.gcloudignoreにファイル名を記載します。

Cloud Functionにデプロイ

ローカルでは、以下のコマンドを実行することでデプロイできます。

gcloud functions deploy event --entry-point=EventHandler --runtime go113 --trigger-http --allow-unauthenticated --set-env-vars DB_USER=XXXX,DB_PASS=YYYYYY,INSTANCE_CONNECTION_NAME=ZZZZZZZZZ,DB_NAME=AAAAA

EventHandlerをエントリーポイントとして、eventというCloudFunctionsインスタンスが生成され、
--set-env-varsで環境変数を設定できます。

以上でデプロイ完了です!
curlでアクセスして確かめてみましょう!

curl -X GET https://us-central1-shootoku-20200502.cloudfunctions.net/event

db connection successが表示されているはずです!
※Cloud Functionsのログで確認できます。

まとめ

以上で、Go×Cloud Functions×CloudSQLのAPI開発デプロイ手順は完了です。

今回のコードはDB接続しただけなので、
あなたのオリジナルのコードをどんどん付け足していきましょう!

Cloud Functionsの開発ノウハウは、今後もアップデートしていくので
よろしくお願いいたします!



本ブログでは他にも
Laravel×Vueのツイッター風SNSアプリチュートリアルや


ポートフォリオサイトの作成〜公開までのプロセス(全8回)
を全て記事にしているので是非ご覧になってみてください!

プログラミング
スポンサーリンク
シェアする
SHOOTをフォローする
WebエンジニアSHOOTのブログ

コメント

タイトルとURLをコピーしました