API Gatewayを使用してAPIの破壊的変更を防ぐ方法
September 11, 2023
APIを開発する際、現在のAPI利用者に問題を引き起こす可能性のある変更を行うことがあります。APIの進化を現在のユーザーに影響を与えずに行うことは重要です。そうでなければ、ユーザーは提供しているサービスに対する信頼を失う可能性があります。これらの問題を完全に回避することは不可能ですが、影響を最小限に抑えたり、重大な変更が発生する前にそれを検出したりすることは可能です。重大な変更は開発段階で特定する必要があり、もし発生した場合、APIゲートウェイがそれらを処理し、クライアントアプリケーションに影響を与えないようにする必要があります。この記事では、APIの重大な変更を防ぐためのベストプラクティスと戦略、そしてAPISIX APIゲートウェイを使用してそれらを処理する方法について探っていきます。
APIの重大な変更とは何か?
ソフトウェア製品は常に進化し、そのAPIも例外ではありません。これらのAPIは、外部のAPI利用者がシステムとやり取りするための主要なインターフェースとして機能し、製品の変更を反映します。APIの変更には、技術的な改善、ビジネス方針の変更、重大なバグの修正など、さまざまな理由があります。簡単に言えば、重大な変更とは、APIを変更した際に、それを使用しているクライアントアプリケーションに問題を引き起こす可能性のある変更のことです。これらの変更の中には、他のものよりも簡単に検出できるものもあります。以下に、重大な変更の例をいくつか挙げます:
- エンドポイントの削除:
GET /users
エンドポイントを削除した場合、それにアクセスしようとするクライアントはエラーを受け取ります。 - エンドポイントのURL変更: エンドポイントのURLを
GET /users
からGET /members
に変更した場合、古いURLを使用しているクライアントは問題に直面します。 - リクエストペイロードの変更: エンドポイントがリクエストで特定のデータを期待している場合、例えば
POST /users
が{ "name": "John" }
を期待しているのに、それを{ "firstName": "John" }
に変更すると、古い形式を送信しているクライアントに混乱を引き起こします。 - レスポンスのフィールド削除または名前変更: クライアントがAPIのレスポンスで特定のフィールドを期待している場合、それらを削除または名前変更すると、クライアントが正常に動作しなくなります。例えば、
{ "id": 1, "name": "John" }
を{ "id": 1, "fullName": "John Doe" }
に変更する場合です。 - データ型の変更: APIのフィールドが文字列であると期待されているのに、それを整数や他の型に変更すると、クライアントに問題を引き起こす可能性があります。例えば、
"age": "25"
を"age": 25
に変更する場合です。 - 認証メカニズムの変更: ベーシック認証からトークンベースの認証に切り替える際に適切な移行を行わないと、既存のクライアントは認証エラーに直面します。
- 必須フィールドの導入:
POST /users
のようなエンドポイントがオプショナルなフィールドを受け取る場合、そのうちの1つを突然必須にすると、そのフィールドを送信していない既存のクライアントは問題に直面します。 - エラーフォーマットの変更: クライアントが特定のエラーフォーマットを理解するようにプログラムされている場合、そのフォーマットを変更すると、クライアント側での適切なエラーハンドリングができなくなる可能性があります。
- HTTPステータスコードの変更: 特定の操作に対するステータスコードを変更すると、クライアントを誤解させる可能性があります。例えば、リソース作成に対して
201 Created
の代わりに200 OK
を返す場合です。 - 古いAPIバージョンのサポート終了: 適切な移行期間を設けずに古いバージョンのサポートを終了すると、それらの古いバージョンに依存しているクライアントは動作しなくなります。
APIの変更はすべて、クライアントアプリケーションに問題を引き起こす可能性があります。APIゲートウェイをバックエンドAPIのフロントドアとして使用する場合、ゲートウェイはルート設定で定義された一連のルールに基づいてリクエストをどこに転送するかを知っており、APIの重大な変更を処理するのに適した場所です。APISIXを使用していくつかのAPI変更を特定する方法を見てみましょう。
リクエスト&レスポンススキーマの検証
ルートに対して厳密なスキーマを定義することで、リクエストとレスポンスの構造が期待通りであることを確認できます。request-validationプラグインを使用して、受信リクエストを検証し、response-rewriteプラグインを使用して、特定の条件に基づいてAPIのレスポンスを書き換えることができます。
ロギング
APISIXは、http-logger、elasticsearch-logger、file-loggerなど、さまざまなロギングプラグインをサポートしています。ロガーを設定してAPIのリクエストとレスポンスデータを保存し、定期的にログを分析して、リクエスト/レスポンスヘッダー、ペイロード構造、またはその他の異常なパターンの変更を検出します。
ルートとアップストリームの監視
ゲートウェイを通過するルートを監視します。以前利用可能だったルートが突然404エラーを返し始めた場合、APIが変更されたか、エンドポイントが非推奨になった可能性があります。APIヘルスチェック機能を有効にして、アップストリームノードの全体的な健全性を継続的に監視します。ノードの1つが失敗し始めたり、通常よりも速くまたは遅く応答したりする場合、基盤となるバックエンドサービスの処理に変更があったことを示している可能性があります。Prometheusなどの監視ツールとAPISIXを統合し、prometheusプラグインを使用します。4xxや5xxエラーの増加率などのメトリクスに基づいてアラートを設定し、APIに重大な変更が発生した可能性を示すことができます。
バージョニングの使用
APIバージョニングは、APIの変更を管理し、これらの変更がAPI利用者アプリケーションに影響を与えないようにするためのプラクティスです。APISIXでバージョニングを設定する方法はさまざまで、URIパス、クエリパラメータ、ヘッダー、またはコンテンツタイプを使用する方法があります。例えば、APIのバージョンを表示するために/v1/users
や/v2/users
のようなウェブアドレスを使用することがあります。これらのバージョンを持つことで、APIの複数のオプションを提供し、API利用者が自分のペースで最新バージョンにアップグレードするタイミングを決定できるようにします。APISIXは、新しいバージョンの問題を解決するまで、すべてのトラフィックを古い安定したバージョンのAPIにリダイレクトすることができます。新しいバージョンに問題が検出された場合、traffic-splitプラグインを使用して、新しい変更を展開しながら古い互換性を維持することができます。
非推奨通知
機能を削除または変更する前に、それらを非推奨としてマークし、利用者が適応するための十分な時間を与えます。APISIXの助けを借りて、ルートを設定して将来の非推奨とその代替について通信することができます。そのために、APISIXはresponse-rewriteを提供しています。
バージョン管理との統合
プルリクエストのレビュアーが重大な変更を発見することを望むかもしれませんが、この方法だけに頼ることは確実ではなく、最終的には失敗する可能性があります。APIにOpenAPI/Swaggerドキュメントがある場合、これらはバージョン管理され、CIパイプラインに含めることができます。APISIXは、API仕様の変更に対してGitなどのバージョン管理システムとの直接的な統合をネイティブにサポートしていません。ただし、APISIXの外部でプロセスを設定することができます。OasdiffやBumpなどのツールを使用してAPI仕様の変更を特定し、APISIXのルートエンドポイントに対してテストを実行するCIパイプライン(GitHub Actionを追加)をトリガーして、重大な変更が導入されていないことを確認できます。
変更を検出する他の方法
Postmanには、現在のAPIバージョンの重大な変更を自動的にチェックするテンプレートがあり、この記事でその仕組みを説明しています。この検出器をCIパイプラインに追加のステップとして追加します。パイプラインが実行されるたびに、重大な変更検出器は現在のAPI仕様を前のものと比較し、違いがあれば通知します。開発スタックに応じて、OpenAPI仕様を比較する他のライブラリもあります。この記事では、新しい変更を本番環境に適用する前に、テストされたデプロイメント戦略を使用して実際にそれらをキャッチする方法をよく説明しています。
まとめ
APIの重大な変更を検出し、防止することは、API利用者との信頼を維持し、サービスの成功を確保するために重要です。APISIXの機能(リクエスト検証、バージョニング、ロギング、監視、アラート)を自動化されたAPI契約テストなどの技術と統合することで、クライアントに悪影響を与えることなくAPIを進化させることができます。