マイクロサービスの API ゲートウェイ パターンを理解する: シンプルなガイド
単一のモノリシック アプリケーションからマイクロサービス アーキテクチャに移行すると、多くの問題が解決されます。これにより、チームが独立して作業し、サービスを個別に展開し、必要に応じてシステムの一部を拡張することができます。ただし、クライアントはこれらすべての独立したサービスとどのように対話するのかという新たな課題も生じます。
10、50、または数百の小さなマイクロサービスがある場合、モバイル アプリまたは Web ページはそれぞれのマイクロサービスに直接接続する必要があるでしょうか?
ここで、API ゲートウェイ パターン が登場します。このガイドでは、API ゲートウェイとは何なのか、なぜそれが必要なのか、そして API ゲートウェイがどのようにマイクロサービス システムを簡素化するのかについて、簡単な言葉と現実世界の例えを使用して詳しく説明します。
現実世界の例え: ホテルの受付係
あなたが大規模な高級リゾートホテルにチェックインしていると想像してください。リゾートにはさまざまな部門があります。
- ハウスキーピング(クリーンシートの場合) ※ルームサービス(お食事) ※コンシェルジュ(ツアー予約担当)
- Billing (請求書を支払うため)
清潔なタオルが必要な場合は、リゾート内を歩いて清掃棟を探す必要はありません。夕食が食べたければ、キッチンのドアをノックする必要はありません。代わりに、フロントデスクの受付に電話してください。
受付担当者がお客様のご要望を伺い、どの部門が解決できるかを判断し、おつなぎするか、対応させていただきます。
このシナリオでは:
- あなたはクライアント (モバイル アプリまたはブラウザ) です。
- 受付は API ゲートウェイです。
- 部門 (ハウスキーピング、ルームサービス、請求) は マイクロサービス です。
問題: クライアントからサービスへの直接通信
ゲートウェイがどのように機能するかを説明する前に、ゲートウェイを「使用しない」場合に何が起こるかを見てみましょう。
e コマース アプリケーションに 3 つの個別のマイクロサービスがあるとします。
- ユーザー サービス (プロファイルを管理)
- 製品サービス (カタログの管理)
- 注文サービス (チェックアウトの管理)
API ゲートウェイがない場合、クライアント アプリは個別のリクエストを各サービスの個別のアドレス (IP または URL) に直接送信する必要があります。
この直接接続アプローチでは、次のような大きな問題が発生します。
- エンドポイントが多すぎる: クライアント アプリは 3 つの個別の URL を記憶する必要があります。サービスを分割したり、そのアドレスを変更したりする場合は、クライアント アプリケーションを更新する必要があります。
- セキュリティの悪夢: 各マイクロサービスは、認証 (ログイン トークンの確認)、SSL 証明書、およびファイアウォール ルールを個別に実装する必要があります。
- ネットワーク オーバーヘッド: クライアントは、単一のページを読み込むためだけに、遅いモバイル ネットワーク上で 3 つの個別のネットワーク リクエストを行う必要がある場合があります (プロファイルの取得、製品詳細の取得、注文履歴の取得など)。
- プロトコルの違い: クライアント アプリでは HTTP/JSON などの標準 Web プロトコルの使用を好む場合がありますが、内部サービスでは gRPC や AMQP などの特殊なプロトコルを使用した方が高速に通信できる場合があります。
解決策: API ゲートウェイ パターン
API ゲートウェイ は、クライアント アプリケーションと内部マイクロサービスの間に位置するヘルパー サーバーです。これは、すべての受信リクエストに対する単一のエントリ ポイントとして機能します。
3 つの異なるサービスを呼び出す代わりに、クライアントは API ゲートウェイに対して 1 つの呼び出しを行います。次に、ゲートウェイはリクエストを正しい内部サービスに転送し、結果を収集してクライアントに送り返します。
API ゲートウェイの主な責任
API ゲートウェイは、単にトラフィックを転送するだけではありません。これにより、「横断的な懸念事項」、つまりすべてのマイクロサービスがコードを記述する必要があるタスクが処理されます。
- ルーティング: ゲートウェイは受信 URL (
/api/v1/ordersなど) を受け取り、それを正しい内部サービス アドレスにマッピングします。 - 認証と認可: ゲートウェイは入口ドアでセキュリティ トークン (JWT など) を検証します。リクエストが無効な場合は即座に拒否されるため、マイクロサービスが未認証のリクエストで CPU サイクルを浪費することがなくなります。
- レート制限: ユーザーが 1 分間に実行できるリクエストの数を制限することで、悪意のあるボットやバグのあるクライアントがシステムにスパム送信するのを防ぎます。
- 負荷分散: ゲートウェイは、単一サーバーの過負荷を防ぐために、受信トラフィックをマイクロサービスの複数のインスタンスに均等に分散できます。
- プロトコル変換: ユーザー向けの JSON リクエストを高性能の内部 gRPC メッセージに変換し、サービスが優先言語で相互に通信できるようにします。
簡単な実装: コード例
ルーティングがいかに簡単になるかを確認するために、API ゲートウェイを設定する 2 つの一般的な方法を見てみましょう。
1. 宣言型ルーティング (Spring Cloud Gateway YAML)
エンタープライズ Java システムでは、多くの場合、単純な構成ファイルを使用してルーティングを構成します。ゲートウェイは、次のルールに基づいてリクエストを自動的に転送します。
spring:
cloud:
gateway:
routes:
- id: user_service_route
uri: http://internal-user-service:8081
predicates:
- Path=/api/users/**
- id: product_service_route
uri: http://internal-product-service:8082
predicates:
- Path=/api/products/**
2. プログラムによるルーティング (Node.js ゲートウェイのモックアップ)
Express を使用して JavaScript で軽量の API ゲートウェイを構築する場合は、次のようになります。
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
const PORT = 3000;
// 1. Simple Security/Authentication Check at the door
const authenticate = (req, res, next) => {
const token = req.headers['authorization'];
if (token === 'secret-handshake-token') {
next(); // Token is valid, proceed
} else {
res.status(401).json({ error: 'Unauthorized Access!' });
}
};
// Apply auth check to all incoming gateway requests
app.use(authenticate);
// 2. Route requests to correct internal microservices
app.use('/api/users', createProxyMiddleware({ target: 'http://localhost:8081', changeOrigin: true }));
app.use('/api/products', createProxyMiddleware({ target: 'http://localhost:8082', changeOrigin: true }));
app.use('/api/orders', createProxyMiddleware({ target: 'http://localhost:8083', changeOrigin: true }));
app.listen(PORT, () => {
console.log(`API Gateway running smoothly on port ${PORT}`);
});
API ゲートウェイ パターンの長所と短所
他のアーキテクチャ上の決定と同様、API ゲートウェイの使用には次のようなトレードオフがあります。
| アドバンテージ (プロ) | デメリット(短所) |
|---|---|
| シンプルなクライアント インターフェイス: クライアントが知っている必要があるのは 1 つのドメイン名だけです。 | 単一障害点: ゲートウェイがダウンすると、アプリケーション全体にアクセスできなくなります。 |
| 集中セキュリティ: ログイン チェック、SSL、CORS を 1 か所で実装します。 | 余分なレイテンシー: リクエストは追加のネットワーク ホップを通過する必要があるため、少し時間がかかります。 |
| コードの重複の減少: すべてのサービスで認証コードとレート制限コードを書き換えることを避けます。 | メンテナンスのオーバーヘッド: サービスが追加、削除、または分割されるたびに、ゲートウェイを更新する必要があります。 |
## 結論
API ゲートウェイ パターンは、最新のマイクロサービス アーキテクチャの基礎です。単一のスマートなエントリ ポイントとして機能することで、クライアント アプリケーションを内部サービス設定の複雑さから守ります。これにより、クライアント側のコードが簡素化され、セキュリティが集中化され、トラフィック管理が効率的に処理されます。
小規模なネットワーク ホップが導入され、実稼働環境で高可用性を実現するようにセットアップする必要がありますが、コードベースがよりクリーンで安全で管理しやすいという利点があるため、成長を続ける分散システムには強く推奨されるパターンとなっています。