GraphQL のおさらい
GraphQL は、Facebook が開発した API クエリ言語であり、従来の REST API よりも柔軟にデータを取得できる仕組みを提供します。
GraphQL の特徴
-
単一のエンドポイント: REST API では複数のエンドポイントが必要ですが、GraphQL では 1 つのエンドポイント (
/graphql
) に対して異なるクエリを送信できます。 - 必要なデータのみ取得: クライアントが必要なフィールドだけを指定して取得できるため、不要なデータ転送を防げます。
- 型システム: API のスキーマが型で定義されており、データ構造を明確に把握できます。
例えば、https://countries.trevorblades.com/
という GraphQL API に対して、以下のようなクエリを送信すると、日本の国情報を取得できます。
{
country(code: "JP") {
name
capital
currency
}
}
このクエリを curl
を使って実行する場合:
curl -X POST https://countries.trevorblades.com/ \
-H "Content-Type: application/json" \
-d '{"query": "{ country(code: \"JP\") { name capital currency } }"}'
レスポンス:
{
"data": {
"country": {
"name": "Japan",
"capital": "Tokyo",
"currency": "JPY"
}
}
}
GraphQL の強力な点は、クエリを変更することで取得するデータを柔軟に調整できることです。例えば、上記クエリからcapital
を除いて実行すると:
curl -X POST https://countries.trevorblades.com/ \
-H "Content-Type: application/json" \
-d '{"query": "{ country(code: \"JP\") { name currency } }"}'
レスポンスからcapital
の内容も無くなった:
{
"data": {
"country": {
"name": "Japan",
"currency": "JPY"
}
}
}
このように、取得したいデータの種類を動的に変更できる点が特徴です。
GraphQL のデメリット
- 複雑さ: クライアントがクエリを設計する必要があり、シンプルな REST API に比べて学習コストが高い。
- キャッシュが難しい: REST API では URL ベースでキャッシュしやすいが、GraphQL は POST リクエストを基本とするため、キャッシュ戦略が複雑になる。
- 負荷の問題: クライアントが複雑なクエリを送信すると、サーバー側の処理負担が増加する可能性がある。
Kong の概要
Kong はオープンソースの API ゲートウェイであり、API の管理、認証、ルーティング、ロードバランシングなどを担います。
Kong の役割
- API 管理: API の公開、認証、制限、監視が可能
- プラグインによる拡張: 認証、キャッシュ、レートリミット、変換などのプラグインを利用可能
- 負荷分散とスケーラビリティ: 複数のバックエンドサービスに対するリクエストを適切に分配
Kongは、RESTful APIだけでなく、GraphQL APIのリクエストも管理できます。特に、GraphQLはその柔軟性と効率的なデータ取得が特徴ですが、これを実際に運用する際に便利なツールがKongです。
Kongで利用できるGraphQL関連のプラグイン
- DeGraphQL: GraphQL APIをRESTful APIのように使えるように変換するプラグイン
- GraphQL Caching: GraphQLレスポンスをキャッシュし、同じリクエストに対する処理負荷を軽減するためのプラグイン
- GraphQL Rate Limiting: GraphQL APIに対するリクエスト数を制限するプラグイン
DeGraphQL プラグインの紹介
DeGraphQL プラグインは、Kong において GraphQL を RESTful API のように扱えるようにするプラグインです。
主な機能:
- GraphQL API へのリクエストを REST 形式で送信できるように変換
- クライアント側で GraphQL クエリを書く必要がなくなる
- 既存の REST API クライアントやツールで利用可能
これにより、GraphQL に詳しくない開発者でも、簡単にデータを取得できます。
デモ: Kong を使って GraphQL へ RESTful のようにアクセス
Service と Route の作成
まず、GraphQL エンドポイントを指す Service を作成し、それに対応する Route を定義します。
# Service の作成
curl -i -X POST http://localhost:8001/services \
--data "name=countries-graphql" \
--data "url=https://countries.trevorblades.com/"
# Route の作成
curl -i -X POST http://localhost:8001/routes \
--data "service.name=countries-graphql" \
--data "paths[]=/dql"
DeGraphQL プラグインの有効化
次に、Service に DeGraphQL プラグインを作成します。このプラグインは Service レイヤーでのみ作成可能 である点に注意してください。
curl -X POST http://localhost:8001/services/countries-graphql/plugins \
--data name="degraphql"
DeGraphQL の Route 設定
最後に、GraphQL クエリの内容を設定するため、DeGraphQL の Routes を作成します。
curl -X POST http://localhost:8001/services/countries-graphql/degraphql/routes \
--data uri='/:country' \
--data query='query ($country:ID!) {
country(code: $country) {
name
native
capital
emoji
currency
languages {
code
name
}
}
}'
Kong 経由で RESTful のようにアクセス
設定が完了したら、Kong を経由して REST API のようにアクセスできるか試してみます。
curl -X GET http://localhost:8000/dql/JP
このリクエストを実行すると、次のようなレスポンスが得られます。
{
"name": "Japan",
"native": "日本",
"capital": "Tokyo",
"emoji": "🇯🇵",
"currency": "JPY",
"languages": [
{
"code": "ja",
"name": "Japanese"
}
]
}
}
このデモでは、Kong の DeGraphQL プラグインを使い、GraphQL API を REST API のように利用する方法を紹介しました。
メリット
- GraphQL に不慣れな開発者でもシンプルな REST API のようにアクセス可能
- 既存の REST クライアントをそのまま利用可能
- API ゲートウェイとして Kong を活用し、柔軟なルーティングが可能
GraphQL Proxy Caching Advanced の紹介
GraphQL Proxy Caching Advanced は、Kong における GraphQL API のキャッシュ機能を強化するプラグインです。GraphQL のレスポンスをキャッシュし、同じリクエストに対するレスポンスの再計算を防ぐことで、パフォーマンスを向上させます。
主な機能:
- リクエストのキャッシュ: 同じクエリに対してキャッシュを適用し、バックエンドの負荷を軽減
- キャッシュの有効期限設定: TTL(Time-To-Live)を設定して、適切な期間キャッシュを保持
- キャッシュのバイパス: 必要に応じて特定のリクエストをキャッシュ対象外に設定可能
GraphQL Proxy Caching Advanced のデモ
プラグインの有効化
まず、対象の Service に対して GraphQL Proxy Caching Advanced を有効にします。
curl -X POST http://localhost:8001/services/countries-graphql/plugins \
--data name="graphql-proxy-cache-advanced" \
--data config.strategy="memory" \
--data config.cache_ttl=300
この設定では、キャッシュ戦略をメモリ(memory
)とし、キャッシュの有効期限を 300 秒(5 分)に設定しています。キャッシュ戦略をRedis
に保存することもできます。
キャッシュの動作確認
まずは1回目、キャッシュなしの状態でリクエストを送信します。
curl -vvv -X GET http://localhost:8000/dql/JP
...
< X-Cache-Key: a3dad8528d327acbab14c19dc9057727fc1bcf0a236d2c95110a174919507dbb
< X-Cache-Status: Miss
< X-Kong-Upstream-Latency: 174
< X-Kong-Proxy-Latency: 12
...
* Connection #0 to host localhost left intact
{"data":{"country":{"name":"Japan","native":"日本","capital":"Tokyo","emoji":"🇯🇵","currency":"JPY","languages":[{"code":"ja","name":"Japanese"}]}}}%
最初のリクエストではバックエンドの GraphQL API にリクエストが送られ、レスポンスが返されます。まだキャッシュがないため、X-Cache-Status: Miss
となっていて、< X-Kong-Upstream-Latency: 174
で示したようにレイテンシが174msかかりました。
続いて、同じリクエストを再度実行すると、
curl -vvv -X GET http://localhost:8000/dql/JP
...
< X-Cache-Key: a3dad8528d327acbab14c19dc9057727fc1bcf0a236d2c95110a174919507dbb
< X-Cache-Status: Hit
< X-Kong-Upstream-Latency: 0
< X-Kong-Proxy-Latency: 1
...
* Connection #0 to host localhost left intact
{"data":{"country":{"name":"Japan","native":"日本","capital":"Tokyo","emoji":"🇯🇵","currency":"JPY","languages":[{"code":"ja","name":"Japanese"}]}}}%
X-Cache-Status: Hit
で示したように、キャッシュが有効になり、Kong から直接レスポンスが返されるようになります。また、< X-Kong-Upstream-Latency: 0
となっているため、Upstream APIへのアクセスがないためレイテンシは0msです。
キャッシュの操作
このプラグインが提供したAPI Endpointを利用して、キャッシュの確認や削除を行うことができます。詳細については https://docs.konghq.com/hub/kong-inc/graphql-proxy-cache-advanced/api/#managing-cache-entities をご参考ください。
GraphQL Proxy Caching Advanced を利用することで、GraphQL API のパフォーマンスを向上させることができます。
- リクエストのキャッシュにより、レスポンスの高速化とバックエンドの負荷軽減が可能
- 適切なキャッシュ戦略と TTL を設定することで、データの鮮度とパフォーマンスのバランスを調整
- キャッシュのバイパスやクリア機能を活用して、柔軟なキャッシュ管理が可能
GraphQL Rate Limiting Advanced の紹介
GraphQL Rate Limiting Advanced は、Kong における GraphQL API に対してリクエスト数の制限を強化するプラグインです。このプラグインにより、過剰なリクエストを防止し、API サービスへの負荷を軽減することができます。
主な機能:
- リクエスト数制限: 特定の時間帯におけるリクエスト数を制限し、サービスの過負荷を防止
- 個別ユーザーに対する制限: ユーザーごとに制限を設定することで、個別の利用状況に対応
- 動的な制限設定: リクエスト数の制限を柔軟に調整できる機能
GraphQL Rate Limiting Advanced のデモ
プラグインの有効化
まず、対象の Service に対して GraphQL Rate Limiting Advanced を有効にします。
curl -i -X POST http://localhost:8001/services/countries-graphql/plugins \
--data name=graphql-rate-limiting-advanced \
--data config.limit=3,100 \
--data config.window_size=60,3600 \
--data config.sync_rate=1
この設定では、1 分間に最大 3 リクエスト、1 時間に最大 100 リクエストまで許可しています。
まとめ
Kongを使うことで、GraphQL APIをより効率的に管理し、セキュリティやパフォーマンスを向上させることができます。DeGraphQLプラグインでRESTfulにGraphQLを扱えるようにしたり、Rate LimitingやCachingで負荷を管理したりすることで、運用の手間が減り、APIの可用性を高めることができます。