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 をアクティブにする] ボタンをクリックします。

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

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

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. テストデータを含むデータベースを作成する
-
Google Cloud コンソールのタイトルバーで、「Cloud Shell をアクティブにする」アイコン(
)をクリックします。プロンプトが表示されたら、[続行] をクリックします。または、Cloud コンソール ウィンドウを選択し、キーボードで G キーを押してから S キーを押すことでも、同じ操作を行えます。
-
次のコマンドを実行して、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
- 次の 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
- 次のコマンドを実行して、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
- 次のコマンドを使用して、データベースにいくつかのテストレコードを追加します。
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 関数を作成する
- 次のコマンドを使用して、最初の Cloud Run functions 関数用のフォルダを作成します。
mkdir ~/lab-files/spanner_get_pets
cd ~/lab-files/spanner_get_pets
- アプリケーション用の 2 つのファイル、
main.py
と requirements.txt
を作成します。
touch main.py requirements.txt
- [エディタを開く] ボタンをクリックします。先ほど作成した
lab-files/spanner_get_pets/requirements.txt
ファイルに、次のコードを追加します。
google-cloud-spanner==3.27.0
-
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)
- [ターミナルを開く] ボタンをクリックします。次に、次のコマンドを使用して Cloud Run functions 関数をデプロイします。トリガーは HTTP トリガーになります。つまり、関数を呼び出すための URL が生成されます(このコマンドが完了するまでに数分かかります)。
gcloud functions deploy spanner_get_pets --runtime python310 --trigger-http --region={{{project_0.default_region|place_holder_text}}} --quiet
- 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 関数を作成する
- 次のコマンドを使用して、2 つ目の Cloud Run functions 関数のフォルダを作成します。
mkdir ~/lab-files/spanner_save_pets
cd ~/lab-files/spanner_save_pets
- アプリケーション用の 2 つのファイル、
main.py
と requirements.txt
を作成します。
touch main.py requirements.txt
- [エディタを開く] ボタンをクリックします。先ほど作成した
lab-files/spanner_save_pets/requirements.txt
ファイルに、次のコードを追加します。
google-cloud-spanner==3.27.0
-
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))
- [ターミナルを開く] ボタンをクリックします。この Cloud Run functions 関数は、Pub/Sub メッセージでトリガーされます。これを機能させるには、まず次のコマンドで Pub/Sub トピックを作成する必要があります。
gcloud pubsub topics create new-pet-topic
- 次のコマンドを使用して 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
- コマンドが完了したら、コンソールで Pub/Sub サービスに移動します。new-pet-topic トピックをクリックして詳細を表示します。
詳細ページで [メッセージ] タブをクリックし、[メッセージをパブリッシュ] ボタンをクリックします。
以下のメッセージを入力し、[パブリッシュ] ボタンをクリックします。注: メッセージは JSON 形式で、関数が機能するためには、示されているように正しいスキーマを使用する必要があります。
{"OwnerName": "Jean", "PetName": "Sally", "PetType": "Frog", "Breed": "Green"}
- 前に実行した
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 エミュレータの起動
- Cloud Shell ターミナルで次のコマンドを実行して、Spanner エミュレータをインストールして起動します。
sudo apt-get install google-cloud-sdk-spanner-emulator
gcloud emulators spanner start
- エミュレータがターミナルを引き継ぐため、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/
- 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
- Python クライアント ライブラリのコードでエミュレータを使用するには、
SPANNER_EMULATOR_HOST
環境変数を設定する必要があります。そのために、次のコードを実行します。
export SPANNER_EMULATOR_HOST=localhost:9010
タスク 5. Spanner データベース「Pets」用の REST API を作成する
- Cloud Run プログラム ファイル用のフォルダを作成し、必要なファイルを追加します。
mkdir ~/lab-files/cloud-run
cd ~/lab-files/cloud-run
touch Dockerfile main.py requirements.txt
- [エディタを開く] ボタンをクリックします。先ほど作成した
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
-
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)
- [ターミナルを開く] ボタンをクリックして以下のコードを実行し、必要なパッケージをインストールします。
pip install -r requirements.txt
- ターミナルで次のコードを実行してプログラムを起動します。
python main.py
-
Cloud Shell ツールバーで、[+] アイコンをもう一度クリックして、3 つ目のターミナルタブを開きます。
-
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
- HTTP GET コマンドを使用して、レコードが追加されたかどうかを確認します。レコードは JSON 形式で返されます。
curl http://localhost:8080/pets
注: 抜かした手順があった場合や、目的の出力が得られない場合は、CloudShell を使用して、タスク 4 から手順をもう一度試してください。
- 「
exit
」と入力して 3 つ目のターミナルタブを閉じ、Ctrl+C
キーを押して 2 つ目のターミナルタブで Python プログラムを停止します。「exit
」と入力して 2 つ目のタブを閉じます。最初のターミナルタブに戻り、Ctrl+C
キーを押してエミュレータを停止します。
注: これらのレコードはエミュレータに追加されました。次に、Cloud Run にデプロイして、実際の Spanner インスタンスを使用します。
タスク 6. アプリを Cloud Run にデプロイする
- Cloud Run にデプロイするには、Docker イメージが必要です。まず、ディレクトリを cloud-run フォルダに変更します。
cd ~/lab-files/cloud-run
- 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
- ターミナルに戻り、次のコードを実行して Docker イメージを作成します(~/lab-files/cloud-run フォルダにいることを確認してください)。
gcloud builds submit --tag=gcr.io/$GOOGLE_CLOUD_PROJECT/spanner-pets-api:v1.0 .
-
API を探索して有効にするの手順に沿って、プロジェクトに対して Cloud Run が有効化されていることを確認します。
-
次に、次のコマンドを使用して 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}}}
- コマンドが完了したら、サービス URL をメモしてクリップボードにコピーします。エミュレータの場合と同様に、curl コマンドを使用して API をテストできます。まず、以下のように URL を格納するための変数を作成します。プレースホルダ(<YOUR_SERVICE_URL_HERE>)の代わりに、
https://...
を含む完全な URL を貼り付けてください。
pets_url=<YOUR_SERVICE_URL_HERE>
- 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
-
これで、レコードが正常に追加されました。コンソールで Cloud Run サービスに移動し、サービスをクリックして詳細を表示し、ログを確認します。各リクエストがログに記録されていることがわかります。
-
レコードが追加されていることも確認できます。
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $pets_url/pets
-
Spanner に移動して、インスタンスとデータベースを調べます。
-
この API は DELETE も実装しています。ターミナルに戻り、次のコマンドを入力してすべてのデータを削除します。
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -X DELETE $pets_url/pets
- コンソールから 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 の商標です。その他すべての社名および製品名は、それぞれ該当する企業の商標である可能性があります。