バージョン管理された API の基盤となるコードベースをどのように管理しますか? 質問する

バージョン管理された API の基盤となるコードベースをどのように管理しますか? 質問する

私は ReST API のバージョン管理戦略について調べてきましたが、基礎となるコードベースの管理方法については、どのバージョン管理戦略にも触れられていないようです。

API に多くの重大な変更を加えるとします。たとえば、Customer リソースを変更して、単一のフィールドではなく個別のフィールドforenameを返すようにします。(この例では、関連する概念を理解しやすいため、URL バージョン管理ソリューションを使用しますが、この質問はコンテンツ ネゴシエーションやカスタム HTTP ヘッダーにも同様に当てはまります)surnamename

現在、 にエンドポイントがありhttp://api.mycompany.com/v1/customers/{id}、 に互換性のない別のエンドポイントがありますhttp://api.mycompany.com/v2/customers/{id}。v1 API のバグ修正とセキュリティ更新は引き続きリリースしていますが、新機能の開発はすべて v2 に集中しています。API サーバーへの変更をどのように記述、テスト、および展開すればよいでしょうか? 少なくとも 2 つの解決策が考えられます。

  • v1 コードベースにはソース管理ブランチ/タグを使用します。v1 と v2 は独立して開発および展開され、必要に応じてリビジョン管理マージを使用して両方のバージョンに同じバグ修正を適用します。これは、以前のバージョンをサポートしながら新しいメジャー バージョンを開発するときにネイティブ アプリのコードベースを管理する方法に似ています。

  • コードベース自体に API バージョンを認識させると、v1 顧客表現と v2 顧客表現の両方を含む単一のコードベースが作成されます。バージョン管理をデプロイメントの問題ではなくソリューション アーキテクチャの一部として扱います。おそらく、名前空間とルーティングの組み合わせを使用して、リクエストが正しいバージョンで処理されるようにします。

ブランチ モデルの明らかな利点は、古い API バージョンを削除するのが簡単だということです。適切なブランチ/タグのデプロイを停止するだけです。ただし、複数のバージョンを実行している場合は、非常に複雑なブランチ構造とデプロイ パイプラインになる可能性があります。「統合コードベース」モデルではこの問題は回避されますが、(私の考えでは) 不要になった非推奨のリソースとエンドポイントをコードベースから削除するのがはるかに難しくなります。単純な正解はおそらくないので、これは主観的なものだとは思いますが、複数のバージョンにまたがる複雑な API を維持している組織がこの問題をどのように解決しているのか、興味があります。

ベストアンサー1

私はあなたが言及した両方の戦略を使用しました。これら 2 つのうち、サポートされるユースケースでは、よりシンプルな 2 番目のアプローチを好みます。つまり、バージョン管理のニーズが単純な場合は、よりシンプルなソフトウェア設計を採用します。

  • 変更数が少ない、変更の複雑さが低い、または変更スケジュールの頻度が低い
  • コードベースの他の部分とほぼ直交する変更: パブリック API は、コード内で「過度な」(この用語の定義は問いません) 分岐を必要とせずに、スタックの他の部分と平和的に共存できます。

このモデルを使用すると、非推奨のバージョンを削除するのはそれほど難しくありませんでした。

  • 優れたテストカバレッジは、廃止されたAPIと関連するバックコードを削除することで、(最小限の)回帰が起こらないことを保証したことを意味します。
  • 適切な命名戦略(APIバージョンのパッケージ名、またはやや見苦しいが、メソッド名にAPIバージョンを付ける)により、関連するコードを簡単に見つけられるようになった。
  • 横断的な懸念はより困難です。複数の API をサポートするためにコア バックエンド システムを変更する場合は、非常に慎重に検討する必要があります。ある時点で、バックエンドのバージョン管理のコスト (上記の「過剰」に関するコメントを参照) が、単一のコードベースの利点を上回ります。

最初のアプローチは、共存するバージョン間の競合を減らすという観点からは確かに簡単ですが、別々のシステムを維持するオーバーヘッドが、バージョンの競合を減らすメリットを上回る傾向がありました。そうは言っても、新しいパブリック API スタックを立ち上げて、別の API ブランチで反復を開始するのは非常に簡単でした。もちろん、世代の損失はほぼすぐに始まり、ブランチはマージ、マージ競合の解決、その他の楽しい作業で混乱しました。

3 番目のアプローチは、アーキテクチャ レイヤーにあります。Facade パターンのバリアントを採用し、API を、適切な Facade インスタンスと通信する、公開されているバージョン管理されたレイヤーに抽象化します。このインスタンスは、独自の API セットを介してバックエンドと通信します。Facade (以前のプロジェクトではアダプターを使用しました) は、自己完結型でテスト可能な独自のパッケージになり、フロントエンド API をバックエンドから独立して、また互いに独立して移行できるようになります。

これは、API バージョンが同じ種類のリソースを公開する傾向があるが、fullname/forename/surname の例のように構造表現が異なる場合は機能します。異なるバックエンド計算に依存し始めると、少し難しくなります。たとえば、「バックエンド サービスは、パブリック API v1 で公開されている、誤って計算された複利を返しました。お客様はこの誤った動作をすでに修正しています。そのため、バックエンドでその計算を更新して v2 まで適用することはできません。そのため、利息計算コードをフォークする必要があります。」という場合などです。幸い、このような状況はまれです。実際、RESTful API の消費者は、理論上はべき等である ted リソースに対する非破壊的な変更であっても、バグごとの下位互換性よりも正確なリソース表現を好みますGET

あなたの最終的な決断を聞くのが楽しみです。

おすすめ記事