arrow_back

Apigee X によるアプリケーションのモダナイゼーション

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

Apigee X によるアプリケーションのモダナイゼーション

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

GSP842

Google Cloud セルフペース ラボのロゴ

概要

Google Cloud の Apigee API Platform を使用すると、既存の API に新しい機能を追加して既存のアプリケーションをモダナイズできます。

このラボでは、まず、Cloud Run にバックエンド サービスをデプロイします。このバックエンド サービスは、Firestore データベースで銀行データ(顧客、口座、ATM、取引)の保存 / 取得を行う REST API を実装します。次に、このバックエンド サービスをプロキシする Apigee API プロキシと、外部サービスからコンテンツを取得してキャッシュに保存する共有フローを作成します。その後、作成した API プロキシからその共有フローを呼び出して、API レスポンスを JavaScript コードで変更します。

目標

このラボでは、次のタスクの実行方法について学びます。

  • Cloud Run にバックエンド サービスをデプロイする
  • Apigee X プロキシを使用してバックエンド サービスをプロキシする
  • 複数のプロキシによって使用される機能のための共有フローを作成する
  • 構成データをプロパティ セットに保存する
  • Service Callout ポリシーを使用してサービスからコンテンツを取得する
  • キャッシュ ポリシーを使用して再利用可能な情報をキャッシュに保存する
  • JavaScript コードを使用してレスポンスのペイロードを変更する

セットアップ

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

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

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

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

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

ラボを開始して Google Cloud コンソールにログインする方法

  1. [ラボを開始] ボタンをクリックします。ラボの料金をお支払いいただく必要がある場合は、表示されるダイアログでお支払い方法を選択してください。 左側の [ラボの詳細] ペインには、以下が表示されます。

    • [Google Cloud コンソールを開く] ボタン
    • 残り時間
    • このラボで使用する必要がある一時的な認証情報
    • このラボを行うために必要なその他の情報(ある場合)
  2. [Google Cloud コンソールを開く] をクリックします(Chrome ブラウザを使用している場合は、右クリックして [シークレット ウィンドウで開く] を選択します)。

    ラボでリソースがスピンアップし、別のタブで [ログイン] ページが表示されます。

    ヒント: タブをそれぞれ別のウィンドウで開き、並べて表示しておきましょう。

    注: [アカウントの選択] ダイアログが表示されたら、[別のアカウントを使用] をクリックします。
  3. 必要に応じて、下のユーザー名をコピーして、[ログイン] ダイアログに貼り付けます。

    {{{user_0.username | "Username"}}}

    [ラボの詳細] ペインでもユーザー名を確認できます。

  4. [次へ] をクリックします。

  5. 以下のパスワードをコピーして、[ようこそ] ダイアログに貼り付けます。

    {{{user_0.password | "Password"}}}

    [ラボの詳細] ペインでもパスワードを確認できます。

  6. [次へ] をクリックします。

    重要: ラボで提供された認証情報を使用する必要があります。Google Cloud アカウントの認証情報は使用しないでください。 注: このラボでご自身の Google Cloud アカウントを使用すると、追加料金が発生する場合があります。
  7. その後次のように進みます。

    • 利用規約に同意してください。
    • 一時的なアカウントなので、復元オプションや 2 要素認証プロセスは設定しないでください。
    • 無料トライアルには登録しないでください。

その後、このタブで Google Cloud コンソールが開きます。

注: Google Cloud のプロダクトやサービスにアクセスするには、ナビゲーション メニューをクリックするか、[検索] フィールドにサービス名またはプロダクト名を入力します。 ナビゲーション メニュー アイコンと検索フィールド

Cloud Shell をアクティブにする

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

  1. Google Cloud コンソールの上部にある「Cloud Shell をアクティブにする」アイコン 「Cloud Shell をアクティブにする」アイコン をクリックします。

  2. ウィンドウで次の操作を行います。

    • Cloud Shell 情報ウィンドウで操作を進めます。
    • Cloud Shell が認証情報を使用して Google Cloud API を呼び出すことを承認します。

接続した時点で認証が完了しており、プロジェクトに各自の Project_ID が設定されます。出力には、このセッションの PROJECT_ID を宣言する次の行が含まれています。

Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}

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

  1. (省略可)次のコマンドを使用すると、有効なアカウント名を一覧表示できます。
gcloud auth list
  1. [承認] をクリックします。

出力:

ACTIVE: * ACCOUNT: {{{user_0.username | "ACCOUNT"}}} To set the active account, run: $ gcloud config set account `ACCOUNT`
  1. (省略可)次のコマンドを使用すると、プロジェクト ID を一覧表示できます。
gcloud config list project

出力:

[core] project = {{{project_0.project_id | "PROJECT_ID"}}} 注: Google Cloud における gcloud ドキュメントの全文については、gcloud CLI の概要ガイドをご覧ください。

タスク 1. Cloud Run にバックエンド サービスをデプロイする

このタスクでは、Cloud Run にバックエンド サービスをデプロイします。

このサービスは、SimpleBank の API を実装します。この API は、顧客、口座、取引、ATM を使用して銀行をシンプルに表現します。SimpleBank サービスは Node.js を使用して構築されており、データは Firestore に保存されます。コードは Docker コンテナにパッケージ化されているため、そのコンテナを Cloud Run にデプロイします。

コード リポジトリのクローンを作成する

  1. SimpleBank サービスのコードを含むリポジトリのクローンを作成するには、Cloud Shell で次のコマンドを実行します。

    git clone --depth 1 https://github.com/GoogleCloudPlatform/training-data-analyst
  2. 作業ディレクトリへのソフトリンクを作成します。

    ln -s ~/training-data-analyst/quests/develop-apis-apigee ~/develop-apis-apigee
  3. REST バックエンドを含むディレクトリに移動するには、次のコマンドを実行します。

    cd ~/develop-apis-apigee/rest-backend
  4. 構成ファイルでリージョンを更新するには、次のコマンドを実行します。

    sed -i "s/us-west1/{{{ project_0.default_region | "REGION" }}}/g" config.sh

プロジェクトを初期化する

プロジェクト初期化スクリプトの init-project.sh は、Cloud Run API をプロジェクトで有効にします。これらの API は、Cloud Run サービスをデプロイするために必要です。

このサービスのデータベースは、ネイティブ モードの Firestore です。1 つのプロジェクトで、1 つの Firestore データベースをネイティブ モードか Datastore モードでホストできます。このスクリプトは、ネイティブ モードの Firestore データベースを作成します。

  1. init-project.sh スクリプトによって実行されるコマンドを表示するには、次のコマンドを入力します。

    cat init-project.sh

    このスクリプトは、Cloud Run API を有効にし、ネイティブ モードの Firestore データベースを作成します。

  2. スクリプトを実行するには、次のコマンドを入力します。

    ./init-project.sh

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 Cloud Run API を有効にして、Firestore データベースを作成する

サービスを初期化する

サービス初期化スクリプトの init-service.sh は、simplebank-rest という名前のサービス アカウントを作成します。このサービス アカウントは、Cloud Run サービスの ID として使用されます。roles/datastore.user ロールが付与されるため、Firestore でデータの読み取りと更新を行うことができます。

サービスを作成する際には、そのサービス用のサービス アカウントを作成して、最小権限の原則に従って権限を付与することをおすすめします。最小権限の原則とは、アカウントに付与する権限を、そのアカウントに固有の機能を実行するために不可欠な権限のみにする原則です。

  1. init-service.sh スクリプトによって実行されるコマンドを表示するには、次のコマンドを入力します。

    cat init-service.sh

    このスクリプトは、サービスによって使用されるサービス アカウントを作成して、roles/datastore.user ロールを追加します。

  2. スクリプトを実行するには、次のコマンドを入力します。

    ./init-service.sh

バックエンド サービスをデプロイする

デプロイ スクリプトの deploy.sh は、現在のディレクトリにあるコードを使用して simplebank サービス アプリケーションをビルドし、simplebank-rest サービス アカウントを使用して Cloud Run にデプロイします。このデプロイ スクリプトは、アプリケーション コードを更新する度に実行することになります。

このサービスは認証アクセスを必要とするようにデプロイされるため、有効な OpenID Connect ID トークンがなければ呼び出すことができません。

  1. deploy.sh スクリプトによって実行されるコマンドを表示するには、Cloud Shell で次のコマンドを入力します。

    cat deploy.sh

    このスクリプトは、Cloud Build を使用してサービスをビルドし、ビルドされた simplebank-grpc サービスを Cloud Run にデプロイします。

注: このデプロイ スクリプトでは、max-instances パラメータを使用して、Cloud Run クラスタのインスタンス数を 1 に制限しています。実際の本番環境サービスでは、このように低い制限を指定することはありません。
  1. このスクリプトを Cloud Run にデプロイするには、次のコマンドを入力します。

    ./deploy.sh

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 バックエンド サービスをデプロイする

サービスをテストする

  1. サービスが実行されていることを確認するために、サービスを呼び出す curl リクエストを実行します。

    export RESTHOST=$(gcloud run services describe simplebank-rest --platform managed --region {{{project_0.default_region |REGION}}} --format 'value(status.url)') echo "export RESTHOST=${RESTHOST}" >> ~/.bashrc curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -X GET "${RESTHOST}/_status"

    RESTHOST 変数を設定するコマンドで、gcloud を使用して simplebank-rest Cloud Run サービスのホスト名を取得した後、この変数を .bashrc ファイルに追加しています。これにより、Cloud Shell が再起動した場合に RESTHOST 変数が再読み込みされるようになります。

    GET /_status コマンドは、API が稼働していることを示す JSON レスポンスを返すだけです。この呼び出しでは、gcloud auth print-identity-token を使用して、Cloud Shell にログインしているユーザーの OpenID Connect ID トークンを取得しています。ここではプロジェクト オーナーのロールでログインしているため、非常に幅広い権限が付与されています。

  2. Firestore への書き込みを行えることを確認するために、顧客を作成する curl リクエストを実行します。

    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -H "Content-Type: application/json" -X POST "${RESTHOST}/customers" -d '{"lastName": "Diallo", "firstName": "Temeka", "email": "temeka@example.com"}'

    POST /customers コマンドによって顧客が作成されます。lastName、firstName、email の各パラメータはいずれも必須です。メールアドレスは一意でなければならず、顧客の ID として使用されます。顧客レコードは Firestore に保存されます。

    注: 「AlreadyExist」というエラーが返される場合は、Firestore データベースが正常に作成されていない可能性があります。データベースを作成するには init-project.sh スクリプトを実行します。
  3. Firestore からの読み取りを行えることを確認するために、作成した顧客を取得する curl リクエストを実行します。

    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -X GET "${RESTHOST}/customers/temeka@example.com"

    GET /customers/ コマンドによって Firestore から顧客レコードが取得されます。

  4. Firestore に追加のサンプルデータを読み込むために、次のコマンドを入力します。

    gcloud firestore import gs://cloud-training/api-dev-quest/firestore/example-data

    この gcloud コマンドは、Firestore のインポート / エクスポート機能を使用して、顧客、口座、ATM をデータベースにインポートします。

  5. ATM のリストを取得するには、次の curl コマンドを実行します。

    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -X GET "${RESTHOST}/atms"
  6. 1 つの ATM を取得するには、次の curl コマンドを実行します。

    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -X GET "${RESTHOST}/atms/spruce-goose"

    このリクエストは、ATM を名前で取得します。レスポンスにはその ATM の緯度と経度が含まれますが、住所は含まれません。

    {"name":"spruce-goose","longitude":-118.408207,"description":"","latitude":33.977601}

    後のタスクで、Apigee と Geocoding API を使用して、特定の ATM を取得した場合に返されるレスポンスに住所を追加します。

タスク 2. Apigee API プロキシを使用してバックエンド サービスをプロキシする

このタスクでは、バックエンド サービスのファサードとして機能する Apigee API プロキシを作成します。API プロキシでは、サービス アカウントを使用して、Cloud Run サービスに OpenID Connect ID トークンを提示できるようにします。

Apigee API プロキシ用のサービス アカウントを作成する

  1. Apigee API プロキシが使用できるサービス アカウントを作成するには、次のコマンドを入力します。

    gcloud iam service-accounts create apigee-internal-access \ --display-name="Service account for internal access by Apigee proxies" \ --project=${GOOGLE_CLOUD_PROJECT}

    この gcloud コマンドは、apigee-internal-access という名前のサービス アカウントを作成します。このサービス アカウントは、Apigee プロキシがバックエンド サービスを呼び出すときに使用されます。

  2. サービスへのアクセスを許可するロールを付与するには、次のコマンドを入力します。

    gcloud run services add-iam-policy-binding simplebank-rest \ --member="serviceAccount:apigee-internal-access@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \ --role=roles/run.invoker --region={{{project_0.default_region |REGION}}} \ --project=${GOOGLE_CLOUD_PROJECT}

    この gcloud コマンドは、simplebank-rest Cloud Run サービスに対する roles/run.invoker ロールをこのサービス アカウントに付与します。これにより、このサービス アカウントでこのサービスを呼び出せるようになります。

  3. 次のコマンドを使用して、バックエンド サービスの URL を取得します。

    gcloud run services describe simplebank-rest --platform managed --region {{{project_0.default_region |REGION}}} --format 'value(status.url)'

    この URL を保存します。API プロキシの作成時に使用します。

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。付与されたロールが検出されるまでに少し時間がかかることがあります。 Apigee API プロキシ用のサービス アカウントを作成する

Apigee コンソールを開く

Apigee コンソールを開くには、次の手順に沿って操作します。

  • Google Cloud コンソールの [検索] フィールドに「Apigee」と入力し、検索結果で [Apigee API Management] をクリックします。

Apigee コンソールが開き、よく使用される場所へのクイックリンクがランディング ページに表示されます。

  • ナビゲーション メニューナビゲーション メニュー)で、[Apigee] の横にある [固定](固定アイコン)をクリックします。

Apigee がナビゲーション メニューに固定されます。

Apigee プロキシを作成する

  1. ナビゲーション メニューで、[プロキシ開発] > [API プロキシ] を選択します。

  2. プロキシ ウィザードを使用して新しいプロキシを作成するには、[+Create] をクリックします。

    バックエンド サービスのリバース プロキシを作成します。

  3. [Proxy template] で、[General template] > [Reverse proxy (Most common)] を選択します。

    注: [OpenAPI spec template] セクション内の [Reverse proxy (Most common)] を選択しないでください。
  4. [Proxy details] で次のように指定します。

    プロパティ
    Proxy name bank-v1
    Base path /bank/v1
    Target (Existing API) バックエンド URL
    注: [Base path] には「/bank-v1」ではなく「/bank/v1」を使用していることを確認してください。

    ターゲットには、このタスクですでに取得した次のようなバックエンド URL を指定する必要があります。

    https://simplebank-rest-mtdtzt7yzq-ue.a.run.app
  5. [Next] をクリックします。

  6. [Deploy (optional)] の設定はデフォルトのままにして、[Create] をクリックします。

ランタイム インスタンスが使用可能であることを確認する

  1. Cloud Shell で、次のコマンドセットを貼り付けて実行します。

    export INSTANCE_NAME=eval-instance; export ENV_NAME=eval; export PREV_INSTANCE_STATE=; echo "waiting for runtime instance ${INSTANCE_NAME} to be active"; while : ; do export INSTANCE_STATE=$(curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" -X GET "https://apigee.googleapis.com/v1/organizations/${GOOGLE_CLOUD_PROJECT}/instances/${INSTANCE_NAME}" | jq "select(.state != null) | .state" --raw-output); [[ "${INSTANCE_STATE}" == "${PREV_INSTANCE_STATE}" ]] || (echo; echo "INSTANCE_STATE=${INSTANCE_STATE}"); export PREV_INSTANCE_STATE=${INSTANCE_STATE}; [[ "${INSTANCE_STATE}" != "ACTIVE" ]] || break; echo -n "."; sleep 5; done; echo; echo "instance created, waiting for environment ${ENV_NAME} to be attached to instance"; while : ; do export ATTACHMENT_DONE=$(curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" -X GET "https://apigee.googleapis.com/v1/organizations/${GOOGLE_CLOUD_PROJECT}/instances/${INSTANCE_NAME}/attachments" | jq "select(.attachments != null) | .attachments[] | select(.environment == \"${ENV_NAME}\") | .environment" --join-output); [[ "${ATTACHMENT_DONE}" != "${ENV_NAME}" ]] || break; echo -n "."; sleep 5; done; echo "***ORG IS READY TO USE***";

    この一連のコマンドでは、Apigee API を使用して、Apigee ランタイム インスタンスが作成されて eval 環境がアタッチされたことを確認します。

  2. インスタンスが使用可能になるまで待ちます。

    ***ORG IS READY TO USE*** というテキストが表示されたら、インスタンスは使用可能です。ラボを開始する前にすでに Apigee 組織が作成されていることがあります。その場合はインスタンスが作成されるまで待つ必要はありません。

    組織の準備ができるまで待つ場合は、その間に、ApigeeApigee X のアーキテクチャAPI と API プロキシの詳細をご覧ください。

API プロキシをデプロイする

  1. ナビゲーション メニューで、[プロキシ開発] > [API プロキシ] を選択し、[bank-v1] をクリックします。

  2. [Deploy] をクリックします。

  3. [Environment] で [eval] を選択します。

  4. [Service account] に、サービス アカウントのメールアドレスを指定します。

    apigee-internal-access@{{{ project_0.project_id | PROJECT }}}.iam.gserviceaccount.com
  5. [Deploy]、[Confirm] の順にクリックします。

  6. eval のデプロイ ステータスを確認し、プロキシがデプロイされるまで待ちます。

API プロキシをテストする

Apigee 組織の eval 環境は、eval.example.com というホスト名を使用して呼び出すことができます。このホスト名を Apigee ランタイム インスタンスの IP アドレスに解決する DNS エントリは、すでにプロジェクト内に作成されています。この DNS エントリは限定公開ゾーンに作成されているため、内部ネットワーク上でのみ表示されます。

Cloud Shell は内部ネットワーク上に存在しないため、Cloud Shell のコマンドではこの DNS エントリを解決できません。プロジェクト内の仮想マシン(VM)は、限定公開ゾーンの DNS にアクセスできます。apigeex-test-vm という名前の仮想マシンが自動的に作成されています。このマシンを使用して API プロキシを呼び出すことができます。

  1. Cloud Shell で、テスト VM への SSH 接続を開きます。

    TEST_VM_ZONE=$(gcloud compute instances list --filter="name=('apigeex-test-vm')" --format "value(zone)") gcloud compute ssh apigeex-test-vm --zone=${TEST_VM_ZONE} --force-key-file-overwrite

    1 つ目の gcloud コマンドでテスト VM のゾーンを取得し、2 つ目のコマンドで VM への SSH 接続を開きます。

  2. 承認するよう求められた場合は、[承認] をクリックします。

    Cloud Shell で確認されるすべての項目について、Enter キーまたは Return キーを押して、デフォルトの入力を指定します。

    プロジェクトのオーナーとしてログインしているため、このマシンへの SSH は許可されます。

    これで、Cloud Shell セッションが VM 内で実行できるようになります。

  3. eval 環境にデプロイした bank-v1 API プロキシを呼び出します。

    curl -i -k "https://eval.example.com/bank/v1/_status"

    -k オプションを指定すると、curl は TLS 証明書の検証をスキップします。このラボの Apigee ランタイムでは、信頼できる認証局(CA)によって作成された証明書ではなく、自己署名証明書を使用します。

    注: 本番環境のユースケースでは、-k オプションを使用して証明書の検証を省略しないでください。

    403 Forbidden ステータス コードが返されて、クライアントに URL を取得する権限がないという内容のエラー メッセージが表示されます。クライアントが必要なトークンをリクエストで渡さなかったために、バックエンド サービスに対するリクエストが拒否されました。API プロキシは正しい ID で実行されていますが、それでも、リクエストで OpenId Connect ID トークンを強制的に送信する必要があります。

  4. bank-v1 プロキシに戻り、[Develop] タブをクリックします。

  5. プロキシの左側のメニューで、[Target endpoints] > [default] セクションの [PreFlow] をクリックします。

  6. 次のコードを探します(URL は異なります)。

    <HTTPTargetConnection> <Properties/> <URL>https://simplebank-rest-zce6j3rjwq-uw.a.run.app</URL> </HTTPTargetConnection> 注: [HTTPTargetConnection] セクションが見つからない場合は、[Proxy Endpoints] セクションではなく [Target Endpoints] セクションの [PreFlow] をクリックしたことを確認してください。
  7. [HTTPTargetConnection] セクションの URL の下に、次のような [Authentication] セクションを追加します。

    <Authentication> <GoogleIDToken> <Audience>AUDIENCE</Audience> </GoogleIDToken> </Authentication>
  8. AUDIENCE は、[HTTPTargetConnection] セクションにすでにある URL 値に置き換えます。コードは、URL 要素と Audience 要素のユーザー固有の URL を除いて、次のようになります。

    <TargetEndpoint name="default"> <PreFlow name="PreFlow"> <Request/> <Response/> </PreFlow> <Flows/> <PostFlow name="PostFlow"> <Request/> <Response/> </PostFlow> <HTTPTargetConnection> <Properties/> <URL>https://simplebank-rest-zce6j3rjwq-uw.a.run.app</URL> <Authentication> <GoogleIDToken> <Audience>https://simplebank-rest-zce6j3rjwq-uw.a.run.app</Audience> </GoogleIDToken> </Authentication> </HTTPTargetConnection> </TargetEndpoint>
  9. [Save]、[Save As New Revision] の順にクリックします。

  10. [Deploy] をクリックします。

  11. [Environment] には eval を使用します。

  12. [Service account] に、サービス アカウントのメールアドレスを指定します。

    apigee-internal-access@{{{ project_0.project_id | PROJECT }}}.iam.gserviceaccount.com
  13. [Deploy]、[Confirm] の順にクリックします。

  14. [Overview] タブをクリックして eval のデプロイ ステータスを確認し、新しいリビジョンがデプロイされるまで待ちます。

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 Apigee プロキシを作成する

  1. SSH ログインがタイムアウトした場合は、Cloud Shell で次のコマンドを実行して接続を再確立します。

    TEST_VM_ZONE=$(gcloud compute instances list --filter="name=('apigeex-test-vm')" --format "value(zone)") gcloud compute ssh apigeex-test-vm --zone=${TEST_VM_ZONE} --force-key-file-overwrite
  2. VM 内でステータス コマンドを再実行します。

    curl -i -k "https://eval.example.com/bank/v1/_status"

    今度は、次のような成功のレスポンス(200)が表示されるはずです。

    HTTP/2 200 x-powered-by: Express content-type: application/json; charset=utf-8 etag: W/"41-x4uozCo6q/yN+kzizriXxryNZvc" x-cloud-trace-context: 5c810a7faa3353bcc085473fd58805b7 date: Thu, 11 Nov 2021 22:54:35 GMT server: Google Frontend content-length: 65 x-request-id: cf109193-6d6f-49a1-b323-7f66f63c5e28 via: 1.1 google {"serviceName":"simplebank-rest","status":"API up","ver":"1.0.0"}

    このレスポンスは、API プロキシがバックエンド サービスの呼び出しに成功したことを示しています。

  3. コマンド exit を入力して SSH セッションを終了し、Cloud Shell に戻ります。

タスク 3. Google Cloud Geocoding API を使用できるようにする

このタスクでは、Geocoding API を有効にします。この API を API プロキシで使用して、SimpleBank サービスから ATM を取得する際にレスポンスに住所の情報を追加します。

  1. Geocoding API を有効にするには、Cloud Shell で次のコマンドを実行します。

    gcloud services enable geocoding-backend.googleapis.com

    次に、Geocoding API にアクセスできる API キーを作成します。

  2. この API キーを作成するには、次のコマンドを実行します。

    API_KEY=$(gcloud alpha services api-keys create --project=${GOOGLE_CLOUD_PROJECT} --display-name="Geocoding API key for Apigee" --api-target=service=geocoding_backend --format "value(response.keyString)") echo "export API_KEY=${API_KEY}" >> ~/.bashrc echo "API_KEY=${API_KEY}" 注: project プロパティが空の文字列に設定されているという内容のエラーが返される場合は、VM の SSH セッションを終了して Cloud Shell に戻っていることを確認してください。

    この gcloud コマンドは、Geocoding API にリクエストを送信できる API キーを作成します。--format パラメータで response の keyString フィールドを選択して API_KEY シェル変数に格納し、その API_KEY 変数を Cloud Shell の .bashrc ファイルに格納しています。

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 Google Cloud Geocoding API を使用できるようにする

  1. 緯度と経度を指定してジオコーディング情報を取得するには、次の curl コマンドを実行します。

    curl "https://maps.googleapis.com/maps/api/geocode/json?key=${API_KEY}&latlng=37.404934,-122.021411"

    このコマンドは、Geocoding API を呼び出して、API キーと、目的の緯度および経度を渡します。レスポンスには、書式設定済みの住所を含む結果の配列が含まれます。その最初の結果の書式設定済み住所を API プロキシで使用して、1 つの ATM の詳細を取得する際に API レスポンスに住所を追加します。

タスク 4. Geocoding API を呼び出す共有フローを作成する

このタスクでは、Google Geocoding API を呼び出すための共有フローを作成します。共有フローを使用すると、ポリシーとリソースを組み合わせて 1 つのフローを作成し、複数の API プロキシや他の共有フローから使用できます。

この共有フローでは次のパターンを使用します。

Lookup Cache、Service Callout、Extract Variables、Populate Cache の各ステップの上にキャッシュ ヒットとキャッシュミスの矢印が示されている

データベースに含まれている ATM の数は限られており、ATM の緯度と経度は変わりません。Geocoding API の過剰な呼び出しを防ぐために、取得した住所をキャッシュに保存して、緯度と経度をキャッシュキーとして使用します。指定された緯度と経度に対応する住所がキャッシュにない場合は、Geocoding API が呼び出されて、返された住所がキャッシュに保存されます。

共有フローを作成する

  1. ナビゲーション メニューで、[Apigee] > [プロキシ開発] > [共有フロー] を選択します。
  2. [+Create] をクリックします。
  3. [Name] を get-address-for-location に設定し、[Create] をクリックします。
  4. [Develop] タブをクリックします。

LookupCache ポリシーを追加する

LookupCache ポリシーで、住所がすでにキャッシュに保存されている場合にその住所を取得します。

  1. 共有フローの左側のメニューで、[Shared Flows] セクションの [default] をクリックします。

  2. [sharedflows/default.xml] ペインで、[Add policy step](Add Policy Step アイコン)をクリックします。

  3. [Create new policy] を選択します。

  4. [Select policy] で、[Traffic Management] > [Lookup Cache] を選択します。

  5. [詳細] セクションで、以下を指定します。

    プロパティ
    Name LC-LookupAddress
    Display Name LC-LookupAddress
  6. [Add]、[LC-LookupAddress] の順にクリックします。

    ポリシーがフローに追加されて、ポリシーの構成 XML がフローの下のペインに表示されます。

  7. LookupCache 構成がペインにあることを確認して、LookupCache 構成を次の内容に置き換えます。

    <LookupCache continueOnError="false" enabled="true" name="LC-LookupAddress"> <CacheResource>AddressesCache</CacheResource> <Scope>Exclusive</Scope> <CacheKey> <KeyFragment ref="geocoding.latitude"/> <KeyFragment ref="geocoding.longitude"/> </CacheKey> <AssignTo>geocoding.address</AssignTo> </LookupCache>

    このポリシーは、指定された緯度と経度に一致するエントリを AddressesCache で探して、見つかった場合はその値を変数 address に割り当てます。

Service Callout ポリシーを追加する

Service Callout ポリシーで Google Geocoding API を呼び出します。

  1. 共有フローの左側のメニューで、[Shared Flows] セクションの [default] をクリックします。

  2. [sharedflows/default.xml] ペインで、[Add policy step](Add Policy Step アイコン)をクリックします。

  3. [Create new policy] を選択します。

  4. [Select policy] で、[Extension] > [Service Callout] を選択します。

  5. [詳細] セクションで、以下を指定します。

    プロパティ
    Name SC-GoogleGeocode
    Display Name SC-GoogleGeocode
  6. [HTTP Target] フィールドは変更せず、[Add]、[SC-GoogleGeocode] の順にクリックします。

  7. ServiceCallout 構成がペインにあることを確認して、ServiceCallout 構成を次の内容に置き換えます。

    <ServiceCallout continueOnError="false" enabled="true" name="SC-GoogleGeocode"> <Request> <Set> <QueryParams> <QueryParam name="latlng">{geocoding.latitude},{geocoding.longitude}</QueryParam> <QueryParam name="key">{geocoding.apikey}</QueryParam> </QueryParams> <Verb>GET</Verb> </Set> </Request> <Response>calloutResponse</Response> <HTTPTargetConnection> <URL>https://maps.googleapis.com/maps/api/geocode/json</URL> </HTTPTargetConnection> </ServiceCallout>

    このポリシーは、geocoding.latitudegeocoding.longitudegeocoding.apikey の各変数を使用して Geocoding API を呼び出します。API 呼び出しのレスポンスは calloutResponse 変数に格納されます。

ExtractVariables ポリシーを追加する

ExtractVariables ポリシーで、Google Geocoding API レスポンスから書式設定済み住所を抽出します。

  1. 共有フローの左側のメニューで、[Shared Flows] セクションの [default] をクリックします。

  2. [sharedflows/default.xml] ペインで、[Add policy step](Add Policy Step アイコン)をクリックします。

  3. [Create new policy] を選択します。

  4. [Select policy] で、[Mediation] > [Extract Variables] を選択します。

  5. [詳細] セクションで、以下を指定します。

    プロパティ
    Name EV-ExtractAddress
    Display Name EV-ExtractAddress
  6. [Add]、[EV-ExtractAddress] の順にクリックします。

  7. ExtractVariables 構成がペインにあることを確認して、ExtractVariables 構成を次の内容に置き換えます。

    <ExtractVariables continueOnError="false" enabled="true" name="EV-ExtractAddress"> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <JSONPayload> <Variable name="address"> <JSONPath>$.results[0].formatted_address</JSONPath> </Variable> </JSONPayload> <Source clearPayload="false">calloutResponse.content</Source> <VariablePrefix>geocoding</VariablePrefix> </ExtractVariables>

    このポリシーは、JSONPath を使用して、calloutResponse メッセージの JSON ペイロードの最初の結果から formatted_addressを抽出します。抽出した住所は geocoding.address 変数に格納されます。

PopulateCache ポリシーを追加する

PopulateCache ポリシーで住所をキャッシュに保存します。

  1. 共有フローの左側のメニューで、[Shared Flows] セクションの [default] をクリックします。

  2. [sharedflows/default.xml] ペインで、[Add policy step](Add Policy Step アイコン)をクリックします。

  3. [Create new policy] を選択します。

  4. [Select policy] で、[Traffic Management] > [PopulateCache] を選択します。

  5. [詳細] セクションで、以下を指定します。

    プロパティ
    Name PC-StoreAddress
    Display Name PC-StoreAddress
  6. [Add]、[PC-StoreAddress] の順にクリックします。

  7. PopulateCache 構成がペインにあることを確認して、PopulateCache 構成を次の内容に置き換えます。

    <PopulateCache continueOnError="false" enabled="true" name="PC-StoreAddress"> <CacheResource>AddressesCache</CacheResource> <Scope>Exclusive</Scope> <Source>geocoding.address</Source> <CacheKey> <KeyFragment ref="geocoding.latitude"/> <KeyFragment ref="geocoding.longitude"/> </CacheKey> <ExpirySettings> <TimeoutInSec>3600</TimeoutInSec> </ExpirySettings> </PopulateCache>

    このポリシーは、address 変数の値を AddressesCache に格納します。その際、LookupCache ポリシーによって使用されるのと同じキー フラグメント(latitude と longitude)を同じ順序で使用します。ExpirySettings/TimeoutInSec の設定で、格納されたデータがキャッシュに保存される期間を 3600 秒(1 時間)に指定しています。

条件に基づいてポリシーをスキップする

特定の緯度と経度に対応する住所がキャッシュで見つかった場合(キャッシュ ヒット)、ServiceCallout、ExtractVariables、PopulateCache の各ポリシーは不要になるため、スキップする必要があります。

  1. 共有フローの左側のメニューで、[Shared Flows] セクションの [default] をクリックします。

    [Code] ペインに default フローが表示されます。このフローには 4 つのポリシーがアタッチされています。

    <SharedFlow name="default"> <Step> <Name>LC-LookupAddress</Name> </Step> <Step> <Name>SC-GoogleGeocode</Name> </Step> <Step> <Name>EV-ExtractAddress</Name> </Step> <Step> <Name>PC-StoreAddress</Name> </Step> </SharedFlow>

    各 Step は、アタッチされたポリシーを指定しています。Name は、アタッチされたポリシーの名前を指定しています。Condition 要素を追加して、ポリシーを実行するかどうかを決定するブール条件を指定することもできます。

    このタスクの最初に確認した、この共有フローのパターンに示されているとおり、キャッシュで住所が見つかった場合は、サービスを呼び出す必要も、データをキャッシュに保存する必要もないため、2 番目から 4 番目までのポリシー ステップをスキップする必要があります。

    LookupCache ポリシーは、キャッシュでアイテムが見つかったかどうかを示す変数を設定します。その lookupcache.{policyName}.cachehit 変数が false の場合は、アイテムが見つからなかったことになります。2 番目から 4 番目までのステップのポリシーは、キャッシュ ヒットがなかった場合にのみ実行する必要があります。

  2. 2 番目から 4 番目までのステップで、Step 要素に次の条件を追加します。

    <Condition>lookupcache.LC-LookupAddress.cachehit == false</Condition>

    すべて追加し終わると、この共有フローは次のようになります。

    <SharedFlow name="default"> <Step> <Name>LC-LookupAddress</Name> </Step> <Step> <Condition>lookupcache.LC-LookupAddress.cachehit == false</Condition> <Name>SC-GoogleGeocode</Name> </Step> <Step> <Condition>lookupcache.LC-LookupAddress.cachehit == false</Condition> <Name>EV-ExtractAddress</Name> </Step> <Step> <Condition>lookupcache.LC-LookupAddress.cachehit == false</Condition> <Name>PC-StoreAddress</Name> </Step> </SharedFlow>
  3. [Save] をクリックします。

  4. [Deploy] をクリックします。

  5. [Environment] には eval を使用します。

  6. [Service Account] は空白のままにして、[Deploy]、[Confirm] の順にクリックします。

    この共有フローは API キーを使用して Geocoding API を呼び出すため、サービス アカウントは必要ありません。

    共有フローをテストするには API プロキシから呼び出す必要があります。

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 Geocoding API を呼び出す共有フローを作成する

タスク 5. 1 つの ATM を取得する際に ATM の住所を追加する

このタスクでは、作成した共有フローを呼び出す FlowCallout ポリシーを API プロキシに追加します。この API プロキシでは、特定の ATM を取得する際に、Cloud Run サービスのレスポンスから緯度と経度を抽出して、それらに対応する住所を取得するためにこの共有フローを呼び出す必要があります。取得した住所は、JavaScript ポリシーによって API レスポンスに追加されます。

API キー用のプロパティ セットを追加する

プロパティ セットを使用すると、無期限のデータを格納して、API プロキシ内から簡単にアクセスできます。プロパティ セットの値で API キーを保持します。

  1. 左側のナビゲーション メニューで、[プロキシ開発] > [API プロキシ] を選択します。

  2. [bank-v1] をクリックし、[Develop] タブを選択します。

  3. プロキシの左側のメニューの [Resources] セクションの [Add resource](Add resource アイコン)をクリックします。

  4. [Resource type] のプルダウンで [Property Set] を選択します。

  5. [Resource name] に geocoding.properties を指定して、[Add] をクリックします。

  6. [geocoding.properties] ペインで、次のプロパティを追加します。

    apikey=<APIKEY>
  7. <APIKEY> は、タスク 3 で作成した API_KEY に置き換えます。

  8. API_KEY を取得するには、Cloud Shell で次のコマンドを使用します。

    echo ${API_KEY}

    geocoding.properties ファイルが次のようになります。

    apikey=AIzaSyC8-B6nt7M240wwZtsxR2O5sb0xznuhQWc

条件フローを作成する

  1. プロキシの左側のメニューで、[Proxy endpoints] セクションの [default] をクリックします。

  2. [proxy-endpoints/default.xml] ペインの [Proxy endpoint: default] の横にある [Add conditional flow](Add conditional flow アイコン)をクリックします。

  3. [Add conditional flow] ダイアログで次の値を指定します。

    プロパティ
    Flow name GetATM
    Description retrieve a single ATM
    Condition type [Path and Verb] を選択
    Path /atms/{name}
    Verb [GET] を選択

    [Target URL] は空白のままにします。

  4. [Add] をクリックします。

    API プロキシは多数のフローで構成されます。各フローは、ポリシーをステップとしてアタッチするための場を提供します。以下の図は API プロキシを表しています。

    プロキシ エンドポイントからターゲット エンドポイントへのリクエストのフローと返されるレスポンスのフロー

    条件フローの構成は、条件が true の場合にのみ実行されます。この条件フローでは、proxy.pathsuffix 変数が /atms/{name} という形式に一致し、request.verb 変数が GET である必要があります。

    このGetATM 条件フローにいくつかのポリシーをアタッチして、それらが GET /atms/{name} リクエストに対してのみ実行されるようにします。それらのポリシーは、バックエンド サービスが呼び出された後に実行される必要があるため、Proxy Endpoint Response 条件フローにアタッチする必要があります。

緯度と経度を抽出する

  1. [Proxy endpoint: default] フローにある [Response] セクションで、[GetATM] の右側にある [Add Policy Step](ポリシー ステップを追加)アイコン(Add Policy Step アイコン)をクリックします。

    注: ステップは、リクエスト側ではなくレスポンス側に追加してください。
  2. [Create new policy] を選択します。

  3. [Select policy] で、[Mediation] > [Extract Variables] を選択します。

  4. [詳細] セクションで、以下を指定します。

    プロパティ
    Name EV-ExtractLatLng
    Display name EV-ExtractLatLng
  5. [Add]、[EV-ExtractLatLng] の順にクリックします。

  6. ExtractVariables 構成がペインにあることを確認して、ExtractVariables 構成を次の内容に置き換えます。

    <ExtractVariables name="EV-ExtractLatLng"> <Source>response</Source> <JSONPayload> <Variable name="latitude"> <JSONPath>$.latitude</JSONPath> </Variable> <Variable name="longitude"> <JSONPath>$.longitude</JSONPath> </Variable> </JSONPayload> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> </ExtractVariables>

    このポリシーは、バックエンド サービスからの GET /atms/{name} JSON レスポンスから latitudelongitude を抽出します。IgnoreUnresolvedVariables 要素が true に設定されているため、レスポンスに latitude と longitude が見つからない場合も処理が続行されます。

共有フローを呼び出す

  1. [Proxy endpoint: default] フローにある [Response] セクションで、[GetATM] の右側にある [Add Policy Step](ポリシー ステップを追加)アイコン(Add Policy Step アイコン)をクリックします。

  2. [Create new policy] を選択します。

  3. [Select policy] で、[Extension] > [Flow Callout] を選択します。

  4. [詳細] セクションで、以下を指定します。

    プロパティ
    Name FC-GetAddress
    Display name FC-GetAddress
    Shared flow [get-address-for-location] を選択
    Condition latitude != null AND longitude != null

    ATM の緯度または経度が取得されなかった場合、住所を特定できないため、ポリシーの手順はスキップされます。

  5. [Add]、[FC-GetAddress] の順にクリックします。

  6. FlowCallout 構成がペインにあることを確認して、FlowCallout 構成を次のように置き換えます。

    <FlowCallout continueOnError="false" enabled="true" name="FC-GetAddress"> <Parameters> <Parameter name="geocoding.latitude">{latitude}</Parameter> <Parameter name="geocoding.longitude">{longitude}</Parameter> <Parameter name="geocoding.apikey">{propertyset.geocoding.apikey}</Parameter> </Parameters> <SharedFlowBundle>get-address-for-location</SharedFlowBundle> </FlowCallout>

    このポリシーは、latitude、longitude、apikey の各変数をパラメータとして設定して共有フローを呼び出します。共有フローによって geocoding.address 変数が設定されます。

住所を追加する

  1. [Proxy endpoint: default] フローにある [Response] セクションで、[GetATM] の右側にある [Add Policy Step](ポリシー ステップを追加)アイコン(Add Policy Step アイコン)をクリックします。

  2. [Create new policy] を選択します。

  3. [Select policy] で、[Extension] > [JavaScript] を選択します。

  4. [詳細] セクションで、以下を指定します。

    プロパティ
    Name JS-AddAddress
    Display name JS-AddAddress
    Javascript file [Create New Resource] を選択
  5. [Add resource] セクションで、次の情報を指定します。

    プロパティ
    Source [Create new file] を選択
    Resource name addAddress.js
  6. [Add] をクリックし、[addAddress.js] を選択します。

  7. [Condition] に「latitude != null AND longitude != null」を指定します。

  8. [Add]、[JS-AddAddress] の順にクリックします。

  9. プロキシの左側のメニューで、[Resources > jsc] セクションの [addAddress.js] をクリックします。

    addAddress.js コードの [Code] ペインは空です。

  10. レスポンスに住所を追加する次の JavaScript コードを追加します。

    // フロー変数 'geocoding.address' を取得します var address = context.getVariable('geocoding.address'); // レスポンスのペイロードを responsePayload オブジェクトに解析します var responsePayload = JSON.parse(context.getVariable('response.content')); try { // レスポンスに住所を追加します responsePayload.address = address; // レスポンス オブジェクトを再度 JSON に変換します context.setVariable('response.content', JSON.stringify(responsePayload)); } catch(e) { // 例外をキャッチします print('Error occurred when trying to add the address to the response.'); }

    このコードは、JSON レスポンスのペイロードをオブジェクトに解析して住所のフィールドを追加し、そのオブジェクトを再度 JSON 文字列に変換してレスポンスに格納します。

    JavaScript ポリシーの外に例外がスローされないようにするために try / catch ブロックが使用されています。例外がキャッチされない場合は障害が発生して、API プロキシの処理が中止されます。

ポリシーが条件付きでスキップされることを確認する

  1. プロキシの左側のメニューで、[Proxy endpoints > default] セクションの [GetATM] をクリックします。

    [Code] ペインに GetATM フローが表示されます。このフローには 3 つのポリシーがアタッチされています。2 つ目のポリシーと 3 つ目のポリシーには条件が設定されています。

    <Flow name="GetATM"> <Description>retrieve a single ATM</Description> <Request/> <Response> <Step> <Name>EV-ExtractLatLng</Name> </Step> <Step> <Condition>latitude != null AND longitude != null</Condition> <Name>FC-GetAddress</Name> </Step> <Step> <Condition>latitude != null AND longitude != null</Condition> <Name>JS-AddAddress</Name> </Step> </Response> <Condition>(proxy.pathsuffix MatchesPath "/atms/{name}") and (request.verb = "GET")</Condition> </Flow>
  2. [Save]、[Save As New Revision] の順にクリックします。

  3. [Deploy] をクリックします。

  4. [Environment] には eval を使用します。

  5. [Service account] に、サービス アカウントのメールアドレスを指定します。

    apigee-internal-access@{{{ project_0.project_id | PROJECT }}}.iam.gserviceaccount.com
  6. [Deploy]、[Confirm] の順にクリックします。

  7. [Overview] タブをクリックして eval のデプロイ ステータスを確認し、新しいリビジョンがデプロイされるまで待ちます。

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 1 つの ATM を取得する際に ATM の住所を追加する

更新した API プロキシをテストする

  1. Cloud Shell で、テスト VM への SSH 接続を開きます。

    TEST_VM_ZONE=$(gcloud compute instances list --filter="name=('apigeex-test-vm')" --format "value(zone)") gcloud compute ssh apigeex-test-vm --zone=${TEST_VM_ZONE} --force-key-file-overwrite
  2. 次のコマンドを使用して、bank-v1 プロキシを呼び出してすべての ATM を取得します。

    curl -i -k "https://eval.example.com/bank/v1/atms"

    レスポンスに住所は含まれません。このリクエストでは GET /atms/{name} のフローは使用されないからです。

  3. 1 つの ATM を取得します。

    curl -i -k "https://eval.example.com/bank/v1/atms/spruce-goose"

    今度は、API プロキシで追加された住所がレスポンスに含まれます。

    {"longitude":-118.408207,"latitude":33.977601,"description":"","name":"spruce-goose","address":"5865 S Campus Center Dr, Los Angeles, CA 90094, USA"}

お疲れさまでした

このラボでは、まず、Cloud Run にバックエンド サービスをデプロイし、そのバックエンド サービスをプロキシする Apigee API プロキシを作成しました。次に、外部サービスからコンテンツを取得してキャッシュに保存する共有フローを作成しました。その後、作成した API プロキシからその共有フローを呼び出して、API レスポンスを JavaScript コードで変更しました。

次のステップと詳細情報

マニュアルの最終更新日: 2024 年 7 月 16 日

ラボの最終テスト日: 2024 年 7 月 16 日

Copyright 2025 Google LLC. All rights reserved. Google および Google のロゴは Google LLC の商標です。その他すべての企業名および商品名はそれぞれ各社の商標または登録商標です。

始める前に

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

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

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

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

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

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

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

ありがとうございます。

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

1 回に 1 つのラボ

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

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

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