🦒

初心者のためのGoogle Cloud API Gatewayの基本

2024/06/12に公開

はじめに

こんにちは、クラウドエース バックエンドエンジニアリング部の廣瀬です。

今回は、Google Cloud の API Gateway について初心者向けに解説を行いたいと思います。
初学者向けということで、API Gateway とは何か?の説明やユースケース、また具体的な実装方法(Terraform)と実装する上での注意点まで説明していきます。

対象読者

  • これから Google Cloud の API Gateway を使い始めたい方
  • API プロキシサービスの選定をしている方

Google Cloud API Gateway とは?

Google Cloud の API Gateway は、Google Cloud 上で API の管理を目的とした、マネージドかつサーバーレスなサービスです。
API Gateway は、バックエンドサービスの前段に配置するサービスで、リバースプロキシのように、クライアントからのリクエストを受け取り、任意のバックエンドサーバーへ転送し、バックエンドサーバーからのレスポンスをクライアントに返す役割を果たします。
そのため、複数のバックエンドサーバーを構成しシステムを構築する場合、API Gateway を配置することによって、一貫したインターフェースを提供することが可能になります。

api-gateway-conncepts

Google Cloud API Gateway の機能

API 管理

API Gateway とバックエンドサーバーの接続の設定は、OpenAPI v2.0 仕様または gRPC API に準拠したファイルを用いて管理します。
仕様に準拠したファイルで各バックエンドサーバーの振る舞いを定義するため、ファイルをそのまま開発者へ展開することができ、API の仕様を容易に共有することが可能なことも利点の一つです。

API の保護

API Gateway は、バックエンドサーバーにリクエストを転送する前に、リクエストをチェックし、不正なリクエストから API を保護することができます。

JWT トークン検証によるユーザー/サービス認証

JWT トークンによるユーザー認証が可能です。
ユーザーが指定した認証方法を使用して、Identity Provider(IdP)によって署名され発行したトークンを検証し、リクエスト元のユーザーを認証することができます。

api-gateway-ninsho

条件を満たした IdP のユーザーの認証も可能ですし、下記の IdP の認証もサポートしております。

また、サービスアカウントの秘密鍵を用いて、JWT トークンを作成し、リクエスト元で使用することで、送信元のサービス間認証も行えます。
サービス間認証を行うことにより、送信元のアプリケーションの認証も行うことができます。

API キーによる保護

Google Cloud の API キーによる API Gateway の API の保護も可能です。
生成した API キーを配布することにより、配布先で API Gateway の API を利用することを許可できます。
また、API キーは、キーの使用を許可する送信元の制限することも可能で、Web サイト/iOS/Android/IP アドレスといった条件で、送信元を制限できます。

モニタリング

API Gateway でバックエンドサービスへリクエストの転送を構築すると、API Gateway によって自動的に下記のようなログと指標を収集することができます。

  • ログ(リクエストごとに Cloud Logging へ出力)
  • レイテンシ
  • バックエンドのレイテンシ
  • リクエスト数
  • リクエストデータのサイズ
    api-gateway-monitoring

API Gateway のユースケース

API Gateway は様々なユースケースに適用できるサービスです。ユースケースを挙げてみます。

ユースケース 内容
マイクロサービス群の管理 複数のマイクロサービス群を管理する場合、API Gateway を前段に配置することで、統一したインターフェースを提供できます。
OpenAPI 等 で定義したファイルにより、開発者側へマイクロサービスの振る舞いを共有できるため、マイクロサービスごとに仕様を確認することがなくなるため効率化が見込めます。
パートナー企業やサードパーティへの統合 パートナー企業やサードパーティへ自社のバックエンドサーバーを公開する場合、利用します。
統一したインターフェースで公開することができるため、利用者へわかりやすいサービスの提供を実現できます。
また、監視を統合できるため、利用状況を管理することが容易になることも利点です。
API のバージョニングの管理 バックエンドサーバーのバージョニング管理目的に利用することもあります。
Open API に準拠したファイルによりエンドポイントごとのルーティングを切り替えることができるため、バックエンドサーバーの新しいバージョンの API への切り替えも、既存のクライアントに影響を与えずに切り替えを実現することができます。

Google Cloud の API Gateway と類似サービス(Cloud Endpoint/Apigee)との比較

サービス API Gateway Cloud Endpoint Apigee
主な利用用途 サーバーレスでの API 管理 API プロキシによるエンドポイント管理 エンタープライズレベルの API 管理
アーキテクチャ 中央集中型アーキテクチャ 分散型アーキテクチャ 分散型アーキテクチャ
API 定義ファイル仕様 Open API v2.0、gRPC Open API v2.0、gRPC apigee は定義ファイルによる設定は不要
セキュリティ API キーの保護/ IdP による Jwt 認証 API キーの保護/ IdP による Jwt 認証 API キーの保護/OAuth 2.0 プロトコルを使用した認証
収益化機能の有無 なし なし あり
コスト
管理する API の規模 中小規模 中小規模 大規模

Cloud Endpoint は、分散型の API 管理サービスであり、Extensible Service Proxy と呼ばれるプロキシをユーザー側で任意の実行環境へデプロイする必要があります。
GKE や Compute Engine などの IaaS な実行環境のプロキシとして配置する場合は Cloud Endpoint を選択するのが良いでしょう。

Apigee は、スケーリング能力や可用性が高いため、大規模かつ多様な API 管理に向いています。
また、API を商品化させる収益化機能や API のレートを設定する機能など、他の API 管理サービスにはない機能も様々実装されております。
大規模かつエンタープライズ向けの API を公開する場合は、Apigee を選択するのが良いでしょう。

API Gateway の構成

API Gateway は「API Config」と「ゲートウェイ」と呼ばれるコンポーネントで構成されています。
両コンポーネントをデプロイすることで、API Gateway は構築されます。

API Config(API 構成)

API Config は、OpenAPI または gRPC で記載した定義ファイルをアップロードすることで作成されます。
API Gateway がバックエンドサーバーへトラフィックを転送する設定は、API Config を参照し決定されます。

ゲートウェイ

ゲートウェイは API Config をホストする Envoy ベースのプロキシです。
ゲートウェイは特定のリージョンにデプロイされるリソースで、ゲートウェイをデプロイすると、外部向けの URL が作成されます。

api-gateway-component

API Gateway の料金

API ゲートウェイの料金は、API の呼び出し回数とデータ転送のデータ量によって計算されます。

  • API の呼び出し回数による料金

    1 か月あたりの API 呼び出し回数 API 呼び出し回数 100 万回あたりの費用
    0 〜 200 万回 $0.00
    200 万回 ~ 10 億回 $3.00
    10 億回超 $1.50
  • データ転送のデータ量による料金

    トラフィックの発信元と宛先 0 ~ 10 TB 10 TB ~ 150 TB 150 TB 以上
    アジア太平洋間の場合 $0.120 $0.085 $0.080

Open API 仕様による API 定義

これまでの説明で Open API 仕様に準拠したファイルにより、API Gateway とバックエンドサーバーの接続を定義すると説明していきました。
では、Open API とはどういった仕様なのか簡単に特徴を記載します。

特徴 説明
標準化された形式 API のエンドポイント、メソッド、パラメータ、応答などを明確に記述するための標準化された仕様で、JSON または YAML 形式で API の構造を定義します。
また、開発者にとって直感的に理解しやすい構造なため、チームに浸透しやすい形式となっています。
構造の詳細はこちらをご確認ください。
ドキュメント生成のしやすさ Swagger UIreDoc のような OpenAPI 仕様からユーザー向けの API ドキュメントを生成するツールを利用することで、開発者向けの資料を自動で生成することができます。
コード生成のしやすさ OpenAPI GeneratorSwagger Codegen のようなツールを利用することで、API を呼び出すクライアント側のコードや、モックサーバーのコードを自動生成することができます。

API Gateway の構築例(Terraform)

ここからは、具体的な実装方法についても記載していきます。
具体的な実装例の説明のために、ここでは API Gateway の構築例を記載します。
gcloud を用いた構築例は、ドキュメントに詳細が記載されているので、本記事では Terraform を用いた Open API で定義した API Config をデプロイする構築例を記載します。

Terraform による構築
  1. Google Cloud API の有効化
gcloud services enable apigateway.googleapis.com         # API Gateway API
gcloud services enable servicemanagement.googleapis.com  # Service Management API
gcloud services enable servicecontrol.googleapis.com     # Service Control API
  1. バックエンドサービスのデプロイ
    バックエンドサービスを任意の実行環境へデプロイしてください。
    本手順では、Cloud Run にデプロイしたバックエンドサーバーと API Gateway の接続を設定します。

  2. API 定義ファイルの作成(Open API)
    Cloud Run へデプロイされたバックエンドサービスの API 定義を Open API v2.0 の仕様に従って作成します。
    ここでは単純な Get メソッドの API を定義しています。

swagger: "2.0"
info:
  title: Hello World API
  description: This API returns a simple "hello, world" message.
  version: "1.0.0"
host: "api-gateway-app-xxxx.a.run.app"
schemes:
  - "https"
basePath: "/"
paths:
  /:
    get:
      summary: Get a hello message
      description: Returns a simple hello world message in JSON format.
      operationId: getHello
      x-google-backend:
        address: { Cloud Runの 公開URL }
        path_translation: { APPEND_PATH_TO_ADDRESS or CONSTANT_ADDRESS }
      produces:
        - "application/json"
      responses:
        200:
          description: A JSON object containing a hello world message.
          schema:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          examples:
            application/json:
              message: "hello, world"
  • x-google-backend
    • address: Cloud Run へデプロイしたバックエンドサーバーの公開 URL を設定
    • path_translation: (省略可)APPEND_PATH_TO_ADDRESSの場合、リクエストパスは、元のリクエストパスを address に付加して計算されます。CONSTANT_ADDRESSの場合、リクエストパスは、address のままとなります。詳細はこちらをご確認ください。
  1. サービスアカウントの作成
    ここから Terraform によりサービスを構築していきます。
    API Gateway を実行するための権限を設定するため、API Gateway に紐付けるサービスアカウントを作成します。
# サービスアカウントの作成
# API Gatewayのサービスアカウントを作成
resource "google_service_account" "api-gateway-service-account" {
  account_id   = "{サービスアカウントIDを設定}"
}
# API GatewayのサービスアカウントにIAMポリシーを付与
resource "google_project_iam_member" "api-gateway-service-account" {
  project = var.project_id
  role = "roles/run.invoker" # 任意のバックエンドサービスに則ったロールを設定
  member = "serviceAccount:${google_service_account.api-gateway-service-account.email}"
}
  • google_project_iam_member.api-gateway-service-account.role
    • Google Cloud のサーバーレス環境で公開する場合、セキュリティ向上のため、必要な権限を持ったアカウント以外アクセスできないようにデプロイすることができます。そのようなサーバーレス環境で動作するアプリケーションへアクセスするための権限を付与します。
      • Cloud Run: roles/run.invoker
      • Cloud Functions: roles/cloudfunctions.invoker
      • App Engine: こちらを参照
  1. API Gateway の作成

API Config/ゲートウェイをデプロイする API Gateway を作成します。

# API Gatewayの作成
resource "google_api_gateway_api" "api-gateway" {
  provider = google-beta
  api_id = "my-api-gateway" # 任意のIDを設定してください。
  project = var.project_id
}
  1. API Config の作成
# API Configの作成
resource "google_api_gateway_api_config" "api_gateway_config" {
  provider = google-beta
  project = var.project_id
  api = google_api_gateway_api.api.api_id
  display_name = "my-api-gateway-config" # 任意のnameを設定してください。
  gateway_config {
    backend_config {
      google_service_account = google_service_account.api-gateway-service-account.email
    }
  }

  openapi_documents {
    document {
      path = "spec.yaml"                  # API定義ファイルのパスを設定
      contents = filebase64("spec.yaml")  # API定義ファイルのパスを設定
    }
  }

  lifecycle {
    create_before_destroy = true
  }
}
  • openapi_documents

    • document の path と contents
      • path: API Gateway へアップロードする API 定義書のファイルパスを設定します。
      • contents: base64 でエンコードされた、API Gateway へアップロードする API 定義書を設定します。filebase64関数を用いて設定します。
  • lifecycle

    • create_before_destroy にはtrueを設定してください。これを設定しないと、API Config を修正する際に、API Config が重複するとエラーが発生します。
  1. ゲートウェイの作成
    ゲートウェイの作成をします。
# ゲートウェイの作成
resource "google_api_gateway_gateway" "api_gateway_gateway" {
  provider = google-beta
  project = var.project_id
  region = var.region
  api_config = google_api_gateway_api_config.api_gateway_config.id # ゲートウェイにAPI Configを紐付けてください。
  gateway_id = "my-api-gateway" # 任意のIDを設定してください。
}
  1. Terraform の apply
    上記の Terraform ファイルを apply すれば、API Gateway がデプロイされます。

実装する上での注意点

Open API v2.0 のみ対応

Open API は現在 v3.1.0 が公開されておりますが、API Gateway でサポートされているのは、Open API v2.0 です。
v2.0 以上のバージョンで記載した API 定義ファイルだと適応できませんので注意が必要です。

API 定義ファイル上で、リクエストパラメータの name は、キャメルケースとスネークケースで識別できない

例えば、以下のようなparametersの定義をした場合、キャメルケースとスネークケースで定義したnameが API Gateway 上では識別してくれず、重複エラーが発生します。
そのため名称の変更が必要になります。

# 重複エラーが発生するparametersの定義
parameters:
  - name: userId
    in: query
    description: ID that identifies the user
    required: true
    type: number
  - name: user_id
    in: query
    description: ID that identifies the user
    required: true
    type: number
# 重複エラー
 Error: Error creating ApiConfig: googleapi: Error 400: Cannot convert to service config.
│ 'location: "unknown location"
│ kind: ERROR
│ message: "Duplicate declaration of field \'user_id\'. Previous location: unknown location"

コールドスタート

API Gateway はゼロスケーリングのサービスです。
そのため、API Gateway に一定時間(15-20 分)トラフィックが発生しない場合、API Gateway のインスタンスは削除され、再度、トラフィックがあった場合、インスタンスの再作成から始まるので、コールドスタートの影響を受けます。
そのため、常に高いレイテンシを考慮する場合は、定期的にコールするなどの考慮が必要になります。(health チェックなどを仕込むといいでしょう。)

まとめ

本記事では、Google Cloud の API Gateway について基本的な部分をまとめました。
API Gateway はサーバーレスかつマネージドなサービスのため、実装や運用のしやすさが個人的には良い点であると思っております。
本記事が API Gateway を利用する際の手助けになれば幸いです。

Discussion