LabKit ADR 001: Go サービスの HTTP ルーティングアプローチ
コンテキスト
LabKit v2 の開発の一環として、go-chi/chi を GitLab のすべての Go サービスの
標準 HTTP ルーターとして採用するかどうか、および LabKit が基盤となるフレームワークを抽象化する Router インターフェースを
公開すべきかどうかを評価しました。
議論(team-tasks#4311)は、 シニアテクニカルリーダーと Go サービスのメンテナーが懸念を提起し、代替案を提案し、方向性を承認できる オープンな議論でした。
ベンチマークを含む調査が team-tasks#4294 で実施されました。
決定
LabKit はルーティングレイヤーを所有しません。LabKit v2 は任意の
net/http互換ハンドラーで動作する 観測性ミドルウェア(トレーシング、アクセスロギング、相関 ID、ヘルスプローブ)を提供します。 サービスは独自のルーターを持ちます。LabKit に Router インターフェースはありません。元の
v2/httpserver.Routerインターフェースは削除されます。 LabKit API の背後にルーターを抽象化することは、明確な利益なしにメンテナンスコストを追加します。 Hyrum’s Law に従って、コンシューマーは必然的に具体的な実装に依存し、 実際には抽象化を維持することが困難になります。Go 1.22 以上の標準ライブラリ
ServeMuxはほとんどのサービスに十分です。最新のServeMuxは メソッドベースのルーティング(GET /path)とパスパラメーター(/items/{id})をサポートしており、 シンプルなルーティング要件を持つサービスのニーズに応えます。高度なルーティングが必要な場合は Chi を推奨します。ルートグルーピング、スコープ付きミドルウェア、 またはサブルーターのマウントを必要とするサービスの場合、
go-chi/chiが推奨の選択肢です。 標準ライブラリのみに依存し、全体を通じてhttp.Handlerを使用し、GitLab ですでに使用されています (Container Registry の移行、Zoekt インデクサー)。LabKit のミドルウェアは任意の標準ライブラリ互換ルーターと構成できる必要があります。 ミドルウェアのシグネチャは
func(http.Handler) http.Handlerを使用します。これは標準ライブラリのServeMux、chi、または他のhttp.Handler互換ルーターで動作します。Lab Bench は高レベルの HTTP 抽象化を所有します。構造化されたサービスシャーシがルーティング抽象化を 必要とする場合(機能分析、規約の強制、または 3 層サービスモデルのため)、その抽象化は LabKit ではなく Lab Bench に属します。
結果
- LabKit v2 を採用するサービスは特定のルーターにロックされません。複雑さのレベルに合ったルーターを選択します。
- LabKit の API サーフェスは小さく安定しています。ミドルウェアが拡張ポイントであり、ルーティングではありません。
- クロスカッティング関係(レートリミット、サーキットブレーカー、認証)は、特定のルーティングフレームワークに 結びつくのではなく、任意のルーターと構成できるミドルウェアとして提供されます。
- すでに chi(Container Registry、Zoekt)または標準ライブラリ(Workhorse、Runner)を使用しているサービスは、 LabKit v2 ミドルウェアを採用するためにルーティングを変更する必要はありません。
- ルーティング抽象化の将来の必要性が生じた場合、サービスシャーシの要件を完全に把握した状態で Lab Bench に導入でき、LabKit で早まって導入するよりも適切です。
代替案
LabKit でデフォルトのルーターとして chi を採用し、
Routerインターフェースを公開する。これは team-tasks#4283 の 元のプロポーザルでした。抽象化が明確な利益なしにメンテナンスコストを追加し、Hyrum’s Law が 実装の交換を実際には不可能にするため、却下されました。すべてのサービスに chi を義務付ける。多くのサービスが標準ライブラリで完全に対応できるシンプルな ルーティングニーズを持っており、それを必要としないサービスに依存関係を義務付けることは「最小限の API サーフェス」原則に反するため、却下されました。
何もしない。共有ミドルウェアの欠如により、LabKit ノーススター戦略で参照されている DX サーベイの結果に文書化されているように、サービス全体で断片化した観測性セットアップにつながるため、 却下されました。
