アーキテクチャ●●●○○

APIゲートウェイ

API Gateway ・ エーピーアイゲートウェイ

多数のAPIの手前に立つ単一の入口。認証・流量制御・振り分け・集約を一手に引き受ける。

✦ 30秒で試す — 航海サービスを細かく分けたら、スマホの画面が遅くなった中継役に3つをまとめて取らせると、画面が出るまでは?予想してみる

概要

APIゲートウェイは、多数の API を提供するシステムの手前に立つ「単一の入口」です。クライアントは個々のバックエンドサービスの場所や構成を知らなくてよく、いつもゲートウェイという一つの窓口にリクエストを送ります。ゲートウェイはそれを適切なサービスへ振り分けると同時に、認証、レート制限、TLS 終端といった「どのAPIにも共通して必要な処理」を一手に引き受けます。

役所の総合受付をイメージすると分かりやすいでしょう。来訪者は各課の部屋番号を覚える必要がなく、受付で身分確認を済ませれば案内してもらえます。各課は本来の業務に集中でき、受付のルールを変えれば全課に一度に適用できます。マイクロサービスアーキテクチャの実運用では、ほぼ必ずこの層が存在します。代表的な実装・サービスには Kong、Apigee、Amazon API Gateway、Envoy ベースのゲートウェイ群などがあります。

なぜ生まれたか

モノリスの時代、API の入口は自然と一つでした。ところがマイクロサービスに分割すると、クライアントは苦しみを背負わされます。注文サービス・在庫サービス・ユーザーサービスがそれぞれ別のホストとポートで動いているとき、モバイルアプリは全サービスのアドレスを知り、それぞれと TLS を張り、画面を一つ描くために何往復も通信しなければなりません。モバイル回線では往復のたびに遅延が積み上がります。さらにサービス側の事情 — 分割・統合・移設 — が起きるたびに、配布済みのクライアントが壊れる。内部構造がそのまま外部に露出してしまうのです。

もう一つの苦しみはサービス側にありました。認証、レート制限、CORS 対応、アクセスログといった横断的関心事を、全サービスがそれぞれの言語・フレームワークで重複実装することになり、実装漏れは即セキュリティホールになります。「入口を一つに集約し、共通処理はそこでまとめて済ませ、内部構成はその後ろに隠す」— APIゲートウェイは、この二つの苦しみへの答えとして定着しました。往復の多さについても、ゲートウェイは答えを持っています。画面に必要な複数の問い合わせをゲートウェイがまとめて引き受け、遅い回線の往復を1回に束ねる「集約」です(詳細で扱います)。Netflix が2013年にオープンソースとして公開した Zuul のように、大規模サービスが自前のゲートウェイを作って公開したことも、この形が広まるきっかけになりました。

詳細

前段に立つ構成

ゲートウェイはすべての外部リクエストの通り道になり、パスやホスト名に基づいて後段のサービスへルーティングします。共通処理を通過済みのリクエストだけが内部に届くため、各サービスは「認証済み・流量制御済み」を前提にビジネスロジックへ集中できます。

WebアプリモバイルAPIゲートウェイ認証・認可レート制限TLS終端ルーティング・集約ログ・メトリクス注文サービス在庫サービスユーザーサービス外部に見えるのは入口だけ内部構成は自由に変えられる
APIゲートウェイの前段配置 — 横断的関心事を入口で一元処理し、内部構成を隠す

引き受ける横断的関心事

ゲートウェイの仕事は大きく分けて4種類あります。第一にルーティング。/orders は注文サービスへ、/users はユーザーサービスへ、といった振り分けに加え、バージョンごとの出し分けやカナリアリリースのような比率制御も担えます。第二にセキュリティ。TLS 終端、JWT などのトークンの検証、APIキーの管理を入口で済ませ、WAF と組み合わせて防御の第一線を張ります。第三に流量の制御。クライアントごとのレート制限やクォータで、特定の利用者の暴走や DDoS 的な負荷から後段を守ります。第四に変換と集約。複数サービスへの問い合わせを束ねて1レスポンスにまとめたり、内部の gRPC を外部向けの REST API に変換したり、キャッシュで後段の負荷を減らしたりします。すべてのトラフィックが通る場所なので、メトリクス収集や分散トレーシングの起点としても最適です。

リバースプロキシとの違い

「それはリバースプロキシでは?」という疑問はもっともで、実際、APIゲートウェイはリバースプロキシの一種です。違いは意識するレイヤにあります。汎用のリバースプロキシがホスト名やパスといった HTTP の器を見て中継するのに対し、APIゲートウェイは「これはどのAPIの、どの操作か」を理解した上で動きます。APIごとの認可ポリシー、利用者ごとのクォータ、APIキーの発行・失効、開発者ポータルでの仕様公開 — つまり「APIを製品として管理する」機能まで含むのがゲートウェイです。リバースプロキシが土台で、その上にAPI管理の層を載せたもの、と捉えると位置づけが明確になります。また、外から内への「南北」トラフィックを扱うのがゲートウェイ、サービス間の「東西」トラフィックを扱うのがサービスメッシュ、という役割分担もよく整理に使われます。

集約 — 遅い往復を1回に束ねる

「なぜ生まれたか」で見た往復の多さに、ゲートウェイがどう効くかを追ってみます。画面を1枚出すのに会員情報・注文履歴・おすすめの3つが要るとき、クライアントが1つずつ取りに行けば、遅いモバイル回線(往復で100ミリ秒を超えることも珍しくありません)を3往復します。ゲートウェイが集約を引き受けると、クライアントは「この画面のデータをください」と1回頼むだけになり、ゲートウェイがデータセンター内の速い回線(往復数ミリ秒)で各サービスを回って、結果を1つの応答にまとめて返します。遅い往復の回数そのものを減らし、減らせない往復を速い場所へ移す — これが集約の効き目です。

おすすめサービス注文サービス会員サービスAPIゲートウェイスマホアプリおすすめサービス注文サービス会員サービスAPIゲートウェイスマホアプリ画面のデータをまとめて要求 モバイル回線会員情報 データセンター内会員ID注文履歴 会員IDを添えて注文の一覧おすすめ 注文履歴を添えておすすめ一覧1つの応答にまとめて返す

後ろの問い合わせが前の結果を必要とする(注文履歴には会員IDが要る)とき、クライアント側で順に呼ぶと遅い往復が直列に積み上がります。ゲートウェイの中なら、その直列の待ちも速い回線の上で済みます。下の部品で、呼び出しのチップをゲートウェイの箱へ運び、モバイル回線の往復の回数と、画面が出るまでの時間の内訳がどう変わるかを確かめてください。

⚡ 体験: 遅い往復を、速い場所へ移す
モバイル回線往復 120 msデータセンター内 — 往復 4 msスマホゲートウェイ認証・振り分け・集約会員サービス注文サービスおすすめサービススマホが1つずつ呼ぶゲートウェイがまとめる会員情報注文履歴おすすめ画面が出るまで(朱 = モバイル回線の往復、青緑 = データセンター内の往復)
モバイル回線の往復3回データセンター内の往復3回画面が出るまで372 ms

画面を1枚出すのに3つのデータが要ります。まず「画面を開く」を押すか、呼び出しのチップをつかんでゲートウェイの箱へ運んでください。

集約には代償もあります。集約の中の1つのサービスが遅いと応答全体が遅れるため、ゲートウェイ側でタイムアウトを切り、取れなかった部分は空で返すといったグレースフルデグラデーションの設計が要ります。また、画面の都合で集約の形がどんどん増えていくと、次の節の問題に行き着きます。

BFF — クライアントの種類ごとに入口を分ける

単一のゲートウェイに全クライアントの要望を詰め込むと、モバイル向けの軽量レスポンスとWeb向けの詳細レスポンスが同居して肥大化していきます。そこで、クライアントの種類ごとに専用のゲートウェイ層を立てるのが BFF(Backend for Frontend)パターンです。モバイル用BFFは画面に必要な情報だけを集約して返し、Web用BFFは SPA に合わせた形に整える。各BFFはそれを使うフロントエンドチームが所有するため、「どのクライアントの都合を優先するか」という綱引きも解消されます。近年は BFF に GraphQL を採用し、クライアント自身が必要なデータの形を宣言できるようにする構成も人気です。

落とし穴 — 単一障害点と太りすぎ

すべてのトラフィックが一点を通る構成は、そのまま弱点にもなります。ゲートウェイが落ちれば全APIが落ちるため、冗長化とスケーリング、そして自身のヘルスチェックは必須です。また全リクエストに1ホップ分の遅延が加わることも忘れてはいけません。もう一つの古典的な失敗が「太りすぎゲートウェイ」です。便利な場所ゆえにビジネスロジックが少しずつ染み出し、気づけばゲートウェイ自体が巨大なモノリスと化して、全チームの変更がそこで渋滞する — これでは何のためにサービスを分割したのか分かりません。ゲートウェイに置いてよいのは横断的関心事まで、ドメインのロジックは後段のサービスに、という線引きを守り続けることが、この構成を健全に保つ鍵になります。

試問

スマホの画面1枚を出すのに、会員情報・注文履歴・おすすめの3つのデータが要ります。スマホとゲートウェイ(入口の中継役)のあいだは遅いモバイル回線(往復120 ms)、ゲートウェイと3つのサービスのあいだはデータセンター内の速い回線(往復4 ms)です。3枚の呼び出しのチップは、「スマホが1つずつ呼ぶ」と「ゲートウェイがまとめる」の2つの箱のあいだで運べ、運ぶたびに画面を開き直して時間を測ります。

✦ 命題挑戦中

サービスの数も回線の速さも変えずに、画面が出るまでの時間を最初の半分(186 ms)以下にせよ

  • 画面を開いて、出るまでの時間を測る
  • 出るまでの時間が 186 ms 以下(最初の 372 ms の半分以下)
⚡ 体験: 画面が出るまでを半分以下にする
モバイル回線往復 120 msデータセンター内 — 往復 4 msスマホゲートウェイ認証・振り分け・集約会員サービス注文サービスおすすめサービススマホが1つずつ呼ぶゲートウェイがまとめる会員情報注文履歴おすすめ画面が出るまで(朱 = モバイル回線の往復、青緑 = データセンター内の往復)
モバイル回線の往復3回データセンター内の往復3回画面が出るまで372 ms

画面を1枚出すのに3つのデータが要ります。「画面を開く」で時間を測れます。呼び出しのチップは、つかんで2つの箱のあいだを運べます(押しても入れ替わります)。