arrow_back

Cloud Run functions と Cloud Run を使用して Spanner アプリケーションをデプロイする

ログイン 参加
700 以上のラボとコースにアクセス

Cloud Run functions と Cloud Run を使用して Spanner アプリケーションをデプロイする

ラボ 1時間 30分 universal_currency_alt クレジット: 1 show_chart 入門
info このラボでは、学習をサポートする AI ツールが組み込まれている場合があります。
700 以上のラボとコースにアクセス

SCBL007

概要

このラボでは、Spanner データベースを利用するアプリケーションを作成して、Cloud Run functions と Cloud Run の両方にデプロイします。また、開発環境で使用するために Spanner エミュレータをインストール、構成し、有効にします。

目標

このラボでは、次の方法について学びます。

  • Spanner データベースへの読み取りと書き込みを行う Cloud Run functions 関数をデプロイする。
  • 開発用に Spanner エミュレータを設定して使用する。
  • Spanner データの読み取りと書き込みを可能にする REST API を構築する。
  • REST API を Google Cloud Run にデプロイする。

設定と要件

[ラボを開始] ボタンをクリックする前に

こちらの説明をお読みください。ラボには時間制限があり、一時停止することはできません。タイマーは、Google Cloud のリソースを利用できる時間を示しており、[ラボを開始] をクリックするとスタートします。

このハンズオンラボでは、シミュレーションやデモ環境ではなく実際のクラウド環境を使って、ご自身でラボのアクティビティを行います。そのため、ラボの受講中に Google Cloud にログインおよびアクセスするための、新しい一時的な認証情報が提供されます。

このラボを完了するためには、下記が必要です。

  • 標準的なインターネット ブラウザ(Chrome を推奨)
注: このラボの実行には、シークレット モードまたはシークレット ブラウジング ウィンドウを使用してください。これにより、個人アカウントと受講者アカウントの競合を防ぎ、個人アカウントに追加料金が発生することを防ぎます。
  • ラボを完了するための時間(開始後は一時停止できません)
注: すでに個人の Google Cloud アカウントやプロジェクトをお持ちの場合でも、このラボでは使用しないでください。アカウントに追加料金が発生する可能性があります。

Google Cloud Shell の有効化

Google Cloud Shell は、デベロッパー ツールと一緒に読み込まれる仮想マシンです。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働します。Google Cloud Shell では、コマンドラインで GCP リソースにアクセスできます。

GCP Console の右上のツールバーにある [Cloud Shell をアクティブにする] ボタンをクリックします。

Cloud Shell アイコン

[続行] をクリックします。

cloudshell_continue

環境のプロビジョニングと接続には少し時間がかかります。接続すると、すでに認証されており、プロジェクトは PROJECT_ID に設定されています。例えば:

Cloud Shell 端末

gcloud は Google Cloud Platform のコマンドライン ツールです。このツールは、Cloud Shell にプリインストールされており、タブ補完がサポートされています。

次のコマンドを使用すると、有効なアカウント名を一覧表示できます。

gcloud auth list

出力:

ACTIVE: *
ACCOUNT: student-01-xxxxxxxxxxxx@qwiklabs.net
To set the active account, run:
    $ gcloud config set account `ACCOUNT`
	

次のコマンドを使用すると、プロジェクト ID を一覧表示できます。

gcloud config list project
	

出力:

[core]
project = <project_ID>
	

出力例:

[core]
project = qwiklabs-gcp-44776a13dea667a6
	

タスク 1. テストデータを含むデータベースを作成する

  1. Google Cloud コンソールのタイトルバーで、「Cloud Shell をアクティブにする」アイコン(Cloud Shell アイコン)をクリックします。プロンプトが表示されたら、[続行] をクリックします。または、Cloud コンソール ウィンドウを選択し、キーボードで G キーを押してから S キーを押すことでも、同じ操作を行えます。

  2. 次のコマンドを実行して、Cloud Build API、Cloud Run API、Eventarc API を有効にします。コマンドを承認するよう求められたら、承認します。

gcloud services enable cloudbuild.googleapis.com gcloud services enable run.googleapis.com gcloud services enable eventarc.googleapis.com
  1. 次の Bash コマンドを実行して、Pets データベースのスキーマ ファイルを作成します。
mkdir ~/lab-files cd ~/lab-files cat > ./pets-db-schema.sql << ENDOFFILE CREATE TABLE Owners ( OwnerID STRING(36) NOT NULL, OwnerName STRING(MAX) NOT NULL ) PRIMARY KEY (OwnerID); CREATE TABLE Pets ( OwnerID STRING(36) NOT NULL, PetID STRING(MAX) NOT NULL, PetType STRING(MAX) NOT NULL, PetName STRING(MAX) NOT NULL, Breed STRING(MAX) NOT NULL, ) PRIMARY KEY (OwnerID,PetID), INTERLEAVE IN PARENT Owners ON DELETE CASCADE ENDOFFILE
  1. 次のコマンドを実行して、Spanner のインスタンスとデータベースを作成します。
gcloud spanner instances create test-spanner-instance --config=regional-{{{project_0.default_region|place_holder_text}}} --description="test-spanner-instance" --processing-units=100 gcloud spanner databases create pets-db --instance=test-spanner-instance --database-dialect=GOOGLE_STANDARD_SQL --ddl-file=./pets-db-schema.sql
  1. 次のコマンドを使用して、データベースにいくつかのテストレコードを追加します。
owner_uuid=$(cat /proc/sys/kernel/random/uuid) gcloud spanner rows insert --table=Owners --database=pets-db --instance=test-spanner-instance --data=OwnerID=$owner_uuid,OwnerName=Doug gcloud spanner rows insert --table=Pets --database=pets-db --instance=test-spanner-instance --data=PetID=$(cat /proc/sys/kernel/random/uuid),OwnerID=$owner_uuid,PetName='Noir',PetType='Dog',Breed='Schnoodle' gcloud spanner rows insert --table=Pets --database=pets-db --instance=test-spanner-instance --data=PetID=$(cat /proc/sys/kernel/random/uuid),OwnerID=$owner_uuid,PetName='Bree',PetType='Dog',Breed='Mutt' gcloud spanner rows insert --table=Pets --database=pets-db --instance=test-spanner-instance --data=PetID=$(cat /proc/sys/kernel/random/uuid),OwnerID=$owner_uuid,PetName='Gigi',PetType='Dog',Breed='Retriever'

タスク 2. Spanner から読み取る Cloud Run functions 関数を作成する

  1. 次のコマンドを使用して、最初の Cloud Run functions 関数用のフォルダを作成します。
mkdir ~/lab-files/spanner_get_pets cd ~/lab-files/spanner_get_pets
  1. アプリケーション用の 2 つのファイル、main.pyrequirements.txt を作成します。
touch main.py requirements.txt
  1. [エディタを開く] ボタンをクリックします。先ほど作成した lab-files/spanner_get_pets/requirements.txt ファイルに、次のコードを追加します。
google-cloud-spanner==3.27.0
  1. lab-files/spanner_get_pets/main.py ファイルに、データベースから読み取ってペットを返す次のコードを追加します。
from google.cloud import spanner instance_id = 'test-spanner-instance' database_id = 'pets-db' client = spanner.Client() instance = client.instance(instance_id) database = instance.database(database_id) def spanner_get_pets(request): query = """SELECT OwnerName, PetName, PetType, Breed FROM Owners JOIN Pets ON Owners.OwnerID = Pets.OwnerID;""" outputs = [] with database.snapshot() as snapshot: results = snapshot.execute_sql(query) output = '<div>OwnerName,PetName,PetType,Breed</div>' outputs.append(output) for row in results: output = '<div>{},{},{},{}</div>'.format(*row) outputs.append(output) return '\n'.join(outputs)
  1. [ターミナルを開く] ボタンをクリックします。次に、次のコマンドを使用して Cloud Run functions 関数をデプロイします。トリガーは HTTP トリガーになります。つまり、関数を呼び出すための URL が生成されます(このコマンドが完了するまでに数分かかります)。
gcloud functions deploy spanner_get_pets --runtime python310 --trigger-http --region={{{project_0.default_region|place_holder_text}}} --quiet
  1. Cloud Run functions 関数をデプロイするコマンドが完了したら、次のコマンドを使用して Cloud Run functions 関数をテストします。テストデータが返されるはずです。
curl -m 70 -X GET https://{{{project_0.default_region|place_holder_text}}}-${GOOGLE_CLOUD_PROJECT}.cloudfunctions.net/spanner_get_pets -H "Authorization: bearer $(gcloud auth print-identity-token)" -H "Content-Type: application/json"

タスク 3. Spanner への書き込みを行う Cloud Run functions 関数を作成する

  1. 次のコマンドを使用して、2 つ目の Cloud Run functions 関数のフォルダを作成します。
mkdir ~/lab-files/spanner_save_pets cd ~/lab-files/spanner_save_pets
  1. アプリケーション用の 2 つのファイル、main.pyrequirements.txt を作成します。
touch main.py requirements.txt
  1. [エディタを開く] ボタンをクリックします。先ほど作成した lab-files/spanner_save_pets/requirements.txt ファイルに、次のコードを追加します。
google-cloud-spanner==3.27.0
  1. lab-files/spanner_save_pets/main.py ファイルに、データベースから読み取ってペットを返す次のコードを追加します。
from google.cloud import spanner import base64 import uuid import json instance_id = 'test-spanner-instance' database_id = 'pets-db' client = spanner.Client() instance = client.instance(instance_id) database = instance.database(database_id) def spanner_save_pets(event, context): pubsub_message = base64.b64decode(event['data']).decode('utf-8') data = json.loads(pubsub_message) # 飼い主がすでに存在するかどうかを確認します with database.snapshot() as snapshot: results = snapshot.execute_sql(""" SELECT OwnerID FROM OWNERS WHERE OwnerName = @owner_name""", params={"owner_name": data["OwnerName"]}, param_types={"owner_name": spanner.param_types.STRING}) row = results.one_or_none() if row != None: owner_exists = True owner_id = row[0] else: owner_exists = False owner_id = str(uuid.uuid4()) # 新しいペットの UUID が必要です pet_id = str(uuid.uuid4()) def insert_owner_pet(transaction, data, owner_exists): try: row_ct = 0 params = { "owner_id": owner_id, "owner_name": data["OwnerName"], "pet_id": pet_id, "pet_name": data["PetName"], "pet_type": data["PetType"], "breed": data["Breed"], } param_types = { "owner_id": spanner.param_types.STRING, "owner_name": spanner.param_types.STRING, "pet_id": spanner.param_types.STRING, "pet_name": spanner.param_types.STRING, "pet_type": spanner.param_types.STRING, "breed": spanner.param_types.STRING, } # 飼い主がまだ存在しない場合のみ、飼い主を追加します if not owner_exists: row_ct = transaction.execute_update( """INSERT Owners (OwnerID, OwnerName) VALUES (@owner_id, @owner_name)""", params=params, param_types=param_types,) # ペットを追加します row_ct += transaction.execute_update( """INSERT Pets (PetID, OwnerID, PetName, PetType, Breed) VALUES (@pet_id, @owner_id, @pet_name, @pet_type, @breed) """, params=params, param_types=param_types,) except: row_ct = 0 return row_ct row_ct = database.run_in_transaction(insert_owner_pet, data, owner_exists) print("{} record(s) inserted.".format(row_ct))
  1. [ターミナルを開く] ボタンをクリックします。この Cloud Run functions 関数は、Pub/Sub メッセージでトリガーされます。これを機能させるには、まず次のコマンドで Pub/Sub トピックを作成する必要があります。
gcloud pubsub topics create new-pet-topic
  1. 次のコマンドを使用して Cloud Run functions 関数をデプロイします(コマンドが完了するまでに数分かかります)。
gcloud functions deploy spanner_save_pets --runtime python310 --trigger-topic=new-pet-topic --region={{{project_0.default_region|place_holder_text}}} --quiet
  1. コマンドが完了したら、コンソールで Pub/Sub サービスに移動します。new-pet-topic トピックをクリックして詳細を表示します。
    詳細ページで [メッセージ] タブをクリックし、[メッセージをパブリッシュ] ボタンをクリックします。
    以下のメッセージを入力し、[パブリッシュ] ボタンをクリックします。: メッセージは JSON 形式で、関数が機能するためには、示されているように正しいスキーマを使用する必要があります。
{"OwnerName": "Jean", "PetName": "Sally", "PetType": "Frog", "Breed": "Green"}
  1. 前に実行した curl コマンドを使用して、spanner_gets_pets Cloud Run functions 関数をトリガーします。新しいオーナーである Jean と、飼っているカエルの Sally が追加されたことを確認します。
curl -m 70 -X GET https://{{{project_0.default_region|place_holder_text}}}-${GOOGLE_CLOUD_PROJECT}.cloudfunctions.net/spanner_get_pets -H "Authorization: bearer $(gcloud auth print-identity-token)" -H "Content-Type: application/json"

タスク 4. Spanner エミュレータの起動

  1. Cloud Shell ターミナルで次のコマンドを実行して、Spanner エミュレータをインストールして起動します。
sudo apt-get install google-cloud-sdk-spanner-emulator gcloud emulators spanner start
  1. エミュレータがターミナルを引き継ぐため、Cloud Shell のツールバーで [+] アイコンをクリックして新しいターミナルタブを開きます。次のコマンドを実行して、エミュレータを使用するように Cloud SDK を構成します。
gcloud config configurations create emulator gcloud config set auth/disable_credentials true gcloud config set project $GOOGLE_CLOUD_PROJECT gcloud config set api_endpoint_overrides/spanner http://localhost:9020/
  1. gcloud を使用してインスタンスとデータベースを作成します。ただし、これらのコマンドは、クラウド内の Spanner ではなくエミュレータを使用していることに注意してください。全体ではなく、それぞれを個別に実行します。
cd ~/lab-files gcloud spanner instances create emulator-instance --config=emulator-config --description="EmulatorInstance" --nodes=1 gcloud spanner databases create pets-db --instance=emulator-instance --database-dialect=GOOGLE_STANDARD_SQL --ddl-file=./pets-db-schema.sql
  1. Python クライアント ライブラリのコードでエミュレータを使用するには、SPANNER_EMULATOR_HOST 環境変数を設定する必要があります。そのために、次のコードを実行します。
export SPANNER_EMULATOR_HOST=localhost:9010

タスク 5. Spanner データベース「Pets」用の REST API を作成する

  1. Cloud Run プログラム ファイル用のフォルダを作成し、必要なファイルを追加します。
mkdir ~/lab-files/cloud-run cd ~/lab-files/cloud-run touch Dockerfile main.py requirements.txt
  1. [エディタを開く] ボタンをクリックします。先ほど作成した lab-files/cloud-run/requirements.txt ファイルに、次のコードを追加します。
Flask==3.0.3 Flask-RESTful==0.3.10 google-cloud-spanner==3.27.0 gunicorn==22.0.0
  1. main.py に以下を追加します。このコードは、Python Flask と Flask-RESTful ライブラリを使用して、Pets データベースの REST API を構築します。
    : ファイルの先頭付近で環境変数が使用されています(11 行目から 20 行目)。Cloud Run にデプロイするときは、これらの変数を実際の Spanner データベースを指すように設定します。変数が設定されていない場合は、デフォルトでエミュレータになります。
import os import uuid from flask import Flask, jsonify, request from flask_restful import Api, Resource from google.api_core import exceptions from google.cloud import spanner from werkzeug.exceptions import BadRequest, NotFound # --- 構成 --- # デフォルトでエミュレータ設定が使用されますが、環境変数を指定するとオーバーライドされます。INSTANCE_ID = os.environ.get("INSTANCE_ID", "emulator-instance") DATABASE_ID = os.environ.get("DATABASE_ID", "pets-db") # --- データベース リポジトリ --- class SpannerRepository: """ Google Cloud Spanner とのデータベースのやり取りをすべて処理するリポジトリ クラス。 これにより、データベース ロジックが API / ビューレイヤから分離されます。""" def __init__(self, instance_id, database_id): spanner_client = spanner.Client() self.instance = spanner_client.instance(instance_id) self.database = self.instance.database(database_id) def list_all_pets(self): """すべてのペットを飼い主情報とともに取得します。""" query = """ SELECT o.OwnerID, o.OwnerName, p.PetID, p.PetName, p.PetType, p.Breed FROM Owners o JOIN Pets p ON o.OwnerID = p.OwnerID """ with self.database.snapshot() as snapshot: results = snapshot.execute_sql(query) # 1. イテレータをマテリアライズして行のリストにします。 # このリストの各「行」は、値の通常の Python リストです。 rows = list(results) # 2. 行がない場合、メタデータが不完全である可能性があります。 # このチェックにより、元の「NoneType」エラーが防止されます。 if not rows: return [] # 3. 行がある場合、メタデータの利用が保証されます。 # 結果セットのメタデータから列名を取得します。 # 注: results.metadata が正しい属性です。 keys = [field.name for field in results.metadata.row_type.fields] # 4. 各行の値のリストとキーを zip ファイルに圧縮して、辞書を作成します。return [dict(zip(keys, row)) for row in rows] def get_pet_by_id(self, pet_id): """ID を指定して 1 匹のペットを取得します。""" query = """ SELECT o.OwnerID, o.OwnerName, p.PetID, p.PetName, p.PetType, p.Breed FROM Owners o JOIN Pets p ON o.OwnerID = p.OwnerID WHERE p.PetID = @pet_id """ params = {"pet_id": pet_id} param_types = {"pet_id": spanner.param_types.STRING} with self.database.snapshot() as snapshot: results = snapshot.execute_sql( query, params=params, param_types=param_types ) # results.one_or_none() は、.keys() メソッドを持つ特殊 Row オブジェクト(リストではない) # を返すため、これが正しく、よりシンプルです。 row = results.one_or_none() if not row: return None return dict(zip(row.keys(), row)) def create_pet_and_owner(self, data): """ 新しいペットを作成します。飼い主が存在しない場合は、飼い主も作成します。 このオペレーション全体が、単一のトランザクションで実行されます。 """ def _tx_create_pet(transaction): pet_id = str(uuid.uuid4()) owner_name = data["OwnerName"] owner_result = transaction.execute_sql( "SELECT OwnerID FROM Owners WHERE OwnerName = @name", params={"name": owner_name}, param_types={"name": spanner.param_types.STRING}, ).one_or_none() if owner_result: owner_id = owner_result[0] else: owner_id = str(uuid.uuid4()) transaction.insert( "Owners", columns=("OwnerID", "OwnerName"), values=[(owner_id, owner_name)], ) pet_columns = ["PetID", "OwnerID", "PetName", "PetType", "Breed"] pet_values = [ pet_id, owner_id, data["PetName"], data["PetType"], data["Breed"], ] transaction.insert("Pets", columns=pet_columns, values=[pet_values]) new_pet_data = { "PetID": pet_id, "OwnerID": owner_id, "OwnerName": owner_name, "PetName": data["PetName"], "PetType": data["PetType"], "Breed": data["Breed"], } return new_pet_data return self.database.run_in_transaction(_tx_create_pet) def delete_pet_by_id(self, pet_id): """トランザクションで ID を指定して 1 匹のペットを削除します。""" def _tx_delete_pet(transaction): return transaction.execute_update( "DELETE FROM Pets WHERE PetID = @pet_id", params={"pet_id": pet_id}, param_types={"pet_id": spanner.param_types.STRING}, ) return self.database.run_in_transaction(_tx_delete_pet) def delete_all_pets_and_owners(self): """すべての飼い主を削除し、それによってすべてのペットも削除します。""" def _tx_delete_all(transaction): return transaction.execute_update("DELETE FROM Owners WHERE true") return self.database.run_in_transaction(_tx_delete_all) # --- API Resources --- db_repo = SpannerRepository(INSTANCE_ID, DATABASE_ID) class PetsList(Resource): def get(self): """すべてのペットのリストを返します。""" pets = db_repo.list_all_pets() return jsonify(pets) def post(self): """新しいペットと、場合によっては新しい飼い主も作成します。""" try: data = request.get_json(force=True) required_fields = ["OwnerName", "PetName", "PetType", "Breed"] if not all(field in data for field in required_fields): raise BadRequest("Missing required fields in JSON payload.") except BadRequest as e: return {"message": str(e)}, 400 try: new_pet = db_repo.create_pet_and_owner(data) return new_pet, 201 except exceptions.GoogleAPICallError as e: return {"message": "Database transaction failed", "error": str(e)}, 500 def delete(self): """すべての飼い主とペットを削除します。""" deleted_count = db_repo.delete_all_pets_and_owners() return {"message": f"{deleted_count} owner record(s) deleted (pets cascaded)."}, 200 class Pet(Resource): def get(self, pet_id): """ID を指定して 1 匹のペットを返します。""" pet = db_repo.get_pet_by_id(pet_id) if pet: return jsonify(pet) raise NotFound("Pet with the specified ID was not found.") def delete(self, pet_id): """ID を指定して 1 匹のペットを削除します。""" try: deleted_count = db_repo.delete_pet_by_id(pet_id) if deleted_count > 0: return {"message": f"Pet with ID {pet_id} was deleted."}, 200 raise NotFound("Pet with the specified ID was not found.") except exceptions.NotFound: raise NotFound("Pet with the specified ID was not found.") def patch(self, pet_id): """このエンドポイントは実装されていません。""" return {"message": "Update operation is not implemented."}, 501 # --- Flask アプリの初期化 --- def create_app(): """Flask アプリを作成して構成する Application Factory。""" app = Flask(__name__) api = Api(app) # API リソースのルーティング api.add_resource(PetsList, "/pets") api.add_resource(Pet, "/pets/<string:pet_id>") # エラー処理の一元化 @app.errorhandler(NotFound) def handle_not_found(e): return jsonify({"message": str(e)}), 404 @app.errorhandler(BadRequest) def handle_bad_request(e): return jsonify({"message": str(e)}), 400 @app.errorhandler(Exception) def handle_generic_error(e): app.logger.error(f"An unhandled exception occurred: {e}", exc_info=True) return jsonify({"message": "An internal server error occurred."}), 500 return app app = create_app() if __name__ == "__main__": # debug=False を本番環境で使用します app.run(host="0.0.0.0", port=8080, debug=True)
  1. [ターミナルを開く] ボタンをクリックして以下のコードを実行し、必要なパッケージをインストールします。
pip install -r requirements.txt
  1. ターミナルで次のコードを実行してプログラムを起動します。
python main.py
  1. Cloud Shell ツールバーで、[+] アイコンをもう一度クリックして、3 つ目のターミナルタブを開きます。

  2. curl を使用して API をテストできます。まず、HTTP POST コマンドを使用してレコードを追加します。

curl -X POST --data '{"OwnerName": "Sue", "PetName": "Sparky", "PetType": "Cat", "Breed": "Alley"}' http://localhost:8080/pets curl -X POST --data '{"OwnerName": "Sue", "PetName": "Pickles", "PetType": "Dog", "Breed": "Shepherd"}' http://localhost:8080/pets curl -X POST --data '{"OwnerName": "Doug", "PetName": "Noir", "PetType": "Dog", "Breed": "Schnoodle"}' http://localhost:8080/pets curl -X POST --data '{"OwnerName": "Doug", "PetName": "Bree", "PetType": "Dog", "Breed": "Mutt"}' http://localhost:8080/pets curl -X POST --data '{"OwnerName": "Joey", "PetName": "Felix", "PetType": "Cat", "Breed": "Tabby"}' http://localhost:8080/pets
  1. HTTP GET コマンドを使用して、レコードが追加されたかどうかを確認します。レコードは JSON 形式で返されます。
curl http://localhost:8080/pets 注: 抜かした手順があった場合や、目的の出力が得られない場合は、CloudShell を使用して、タスク 4 から手順をもう一度試してください。
  1. exit」と入力して 3 つ目のターミナルタブを閉じ、Ctrl+C キーを押して 2 つ目のターミナルタブで Python プログラムを停止します。「exit」と入力して 2 つ目のタブを閉じます。
    最初のターミナルタブに戻り、Ctrl+C キーを押してエミュレータを停止します。
注: これらのレコードはエミュレータに追加されました。次に、Cloud Run にデプロイして、実際の Spanner インスタンスを使用します。

タスク 6. アプリを Cloud Run にデプロイする

  1. Cloud Run にデプロイするには、Docker イメージが必要です。まず、ディレクトリを cloud-run フォルダに変更します。
cd ~/lab-files/cloud-run
  1. Docker イメージを作成するには、Dockerfile ファイルに指示を追加する必要があります。[エディタを開く] ボタンをクリックして、Dockerfile ファイルを開きます。次のコードを貼り付けます。
FROM python:3.9 WORKDIR /app COPY . . RUN pip install gunicorn RUN pip install -r requirements.txt ENV PORT=8080 CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 main:app
  1. ターミナルに戻り、次のコードを実行して Docker イメージを作成します(~/lab-files/cloud-run フォルダにいることを確認してください)。
gcloud builds submit --tag=gcr.io/$GOOGLE_CLOUD_PROJECT/spanner-pets-api:v1.0 .
  1. API を探索して有効にするの手順に沿って、プロジェクトに対して Cloud Run が有効化されていることを確認します。

  2. 次に、次のコマンドを使用して Cloud Run アプリケーションをデプロイします。コードがエミュレータではなく Cloud Spanner インスタンスを使用するように、コマンドで環境変数が設定されていることに注意してください。コマンドが完了するまでに数分かかります。

gcloud run deploy spanner-pets-api --image gcr.io/$GOOGLE_CLOUD_PROJECT/spanner-pets-api:v1.0 --update-env-vars INSTANCE_ID=test-spanner-instance,DATABASE_ID=pets-db --region={{{project_0.default_region|place_holder_text}}}
  1. コマンドが完了したら、サービス URL をメモしてクリップボードにコピーします。エミュレータの場合と同様に、curl コマンドを使用して API をテストできます。まず、以下のように URL を格納するための変数を作成します。プレースホルダ(<YOUR_SERVICE_URL_HERE>)の代わりに、https://... を含む完全な URL を貼り付けてください。
pets_url=<YOUR_SERVICE_URL_HERE>
  1. curl を使用してレコードを追加します。
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -X POST --data '{"OwnerName": "Sue", "PetName": "Sparky", "PetType": "Cat", "Breed": "Alley"}' $pets_url/pets curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -X POST --data '{"OwnerName": "Sue", "PetName": "Pickles", "PetType": "Dog", "Breed": "Shepherd"}' $pets_url/pets curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -X POST --data '{"OwnerName": "Doug", "PetName": "Noir", "PetType": "Dog", "Breed": "Schnoodle"}' $pets_url/pets curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -X POST --data '{"OwnerName": "Doug", "PetName": "Bree", "PetType": "Dog", "Breed": "Mutt"}' $pets_url/pets curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -X POST --data '{"OwnerName": "Joey", "PetName": "Felix", "PetType": "Cat", "Breed": "Tabby"}' $pets_url/pets
  1. これで、レコードが正常に追加されました。コンソールで Cloud Run サービスに移動し、サービスをクリックして詳細を表示し、ログを確認します。各リクエストがログに記録されていることがわかります。

  2. レコードが追加されていることも確認できます。

curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $pets_url/pets
  1. Spanner に移動して、インスタンスとデータベースを調べます。

  2. この API は DELETE も実装しています。ターミナルに戻り、次のコマンドを入力してすべてのデータを削除します。

curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -X DELETE $pets_url/pets
  1. コンソールから Spanner インスタンスを削除して、課金されないようにします。

これで完了です。Spanner データベースを利用するアプリケーションを作成して、Cloud Run functions と Cloud Run の両方にデプロイしました。また、開発環境で使用するために Spanner エミュレータをインストール、構成し、有効にしました。

ラボを終了する

ラボでの学習が完了したら、[ラボを終了] をクリックします。ラボで使用したリソースが Qwiklabs から削除され、アカウントの情報も消去されます。

ラボの評価を求めるダイアログが表示されたら、星の数を選択してコメントを入力し、[送信] をクリックします。

星の数は、それぞれ次の評価を表します。

  • 星 1 つ = 非常に不満
  • 星 2 つ = 不満
  • 星 3 つ = どちらともいえない
  • 星 4 つ = 満足
  • 星 5 つ = 非常に満足

フィードバックを送信しない場合は、ダイアログ ボックスを閉じてください。

フィードバック、ご提案、修正事項がございましたら、[サポート] タブからお知らせください。

Copyright 2024 Google LLC All rights reserved. Google および Google のロゴは、Google LLC の商標です。その他すべての社名および製品名は、それぞれ該当する企業の商標である可能性があります。

始める前に

  1. ラボでは、Google Cloud プロジェクトとリソースを一定の時間利用します
  2. ラボには時間制限があり、一時停止機能はありません。ラボを終了した場合は、最初からやり直す必要があります。
  3. 画面左上の [ラボを開始] をクリックして開始します

シークレット ブラウジングを使用する

  1. ラボで使用するユーザー名パスワードをコピーします
  2. プライベート モードで [コンソールを開く] をクリックします

コンソールにログインする

    ラボの認証情報を使用して
  1. ログインします。他の認証情報を使用すると、エラーが発生したり、料金が発生したりする可能性があります。
  2. 利用規約に同意し、再設定用のリソースページをスキップします
  3. ラボを終了する場合や最初からやり直す場合を除き、[ラボを終了] はクリックしないでください。クリックすると、作業内容がクリアされ、プロジェクトが削除されます

このコンテンツは現在ご利用いただけません

利用可能になりましたら、メールでお知らせいたします

ありがとうございます。

利用可能になりましたら、メールでご連絡いたします

1 回に 1 つのラボ

既存のラボをすべて終了して、このラボを開始することを確認してください

シークレット ブラウジングを使用してラボを実行する

このラボの実行には、シークレット モードまたはシークレット ブラウジング ウィンドウを使用してください。これにより、個人アカウントと受講者アカウントの競合を防ぎ、個人アカウントに追加料金が発生することを防ぎます。