golang-uber-fx
uber-go/fxを使ったGolangアプリケーションフレームワークのスキルで、`fx.New`・`fx.Provide`・`fx.Invoke`・`fx.Module`・`fx.Lifecycle`フック・`fx.Annotate`・`fx.Decorate`・`fx.Supply`・`fx.Replace`・`fx.WithLogger`およびシグナル対応の`Run()`を扱います。コードベースが`go.uber.org/fx`をインポートしている場合や、`fx.New`でサービスを組み立てる際に適用してください。ライフサイクル管理を伴わない素のDIが必要な場合は`golang-uber-dig`スキルを参照してください。
description の原文を見る
Golang application framework using uber-go/fx — fx.New, fx.Provide, fx.Invoke, fx.Module, fx.Lifecycle hooks, fx.Annotate (name/group/As), fx.Decorate, fx.Supply, fx.Replace, fx.WithLogger, and signal-aware Run(). Apply when using or adopting uber-go/fx, when the codebase imports `go.uber.org/fx`, or when wiring services with fx.New. For raw DI without lifecycle, see `samber/cc-skills-golang@golang-uber-dig` skill.
SKILL.md 本文
ペルソナ: fxを使ってロングランニングサービスを構築するGoアーキテクト。コンポジションルートでグラフを配線し、init()ではなくフックにライフサイクルを組み込み、モジュールを再利用の単位として扱う。
Go における uber-go/fx を用いたアプリケーション配線
リフレクションベースの DI コンテナ(uber-go/dig 上に構築)、ライフサイクル、モジュールシステム、シグナル対応実行ループ、および構造化イベントログを組み合わせたアプリケーションフレームワーク。ブート順序、グレースフルシャットダウン、モジュール構成が重要なロングランニングサービス向けです。
公式リソース:
このスキルは網羅的ではありません。詳細についてはライブラリドキュメントとコード例を参照してください。Context7 は検索プラットフォームとして役立ちます。
go get go.uber.org/fx
fx vs. dig
fx は dig の上に構築されており、同じリフレクションベースのコンテナエンジンを共有しています。DI プリミティブ(Provide, Invoke, In/Out 構造体、名前付き値、値グループ)は同一です — fx.In/fx.Out は dig.In/dig.Out の再エクスポートです。
fx が追加するもの:
| 関心事 | dig | fx |
|---|---|---|
| DI コンテナ | ✅ dig.New() | ✅ (組み込み) |
| ライフサイクルフック | ❌ | ✅ fx.Lifecycle OnStart/OnStop |
| モジュールシステム | ❌ | ✅ スコープ付きデコレータを備えた fx.Module |
| シグナル対応実行ループ | ❌ | ✅ SIGINT/SIGTERM をブロックする app.Run() |
| 構造化イベントログ | ❌ | ✅ fx.WithLogger / fxevent |
| スタートアップ/シャットダウンタイムアウト | ❌ | ✅ fx.StartTimeout / fx.StopTimeout |
fx を選択 ロングランニングサービス(HTTP サーバー、ワーカー、デーモン)の場合 — ライフサイクルとシグナルハンドリングは必須であり、モジュールは大規模なサービスグラフを管理しやすくします。
raw dig を選択 フレームワークなしで配線が必要な場合: CLI ツール、コンテナをコーラーに公開するライブラリ、テストハーネス、または独自のライフサイクルを管理する既存アプリへの DI の埋め込み。samber/cc-skills-golang@golang-uber-dig スキルを参照してください。
アプリケーション
import "go.uber.org/fx"
app := fx.New(
fx.Provide(NewLogger, NewDatabase, NewServer),
fx.Invoke(RegisterRoutes),
)
app.Run() // SIGINT/SIGTERM までブロック、その後 OnStop フックを実行
ブートステージ: fx.New は型を検証します(コンストラクタは実行されません);app.Start(ctx) は各 fx.Invoke を実行しトポロジカル順序で OnStart フックを発火させます;メインは app.Done() でブロックします;app.Stop(ctx) は OnStop フックを逆順で発火させます。デフォルトタイムアウトは 15秒 — fx.StartTimeout / fx.StopTimeout でオーバーライド可能です。
Provide と Invoke
fx.New(
fx.Provide(NewLogger, NewDatabase, NewServer), // 遅延実行
fx.Invoke(RegisterRoutes, StartMetricsExporter), // Start 中に常に実行
)
fx.Provide はコンストラクタを登録します;fx.Invoke はトリガーです — 型を参照する Invoke(直接または推移的に)がない場合、そのコンストラクタは実行されません。
ライフサイクルフック
fx.Lifecycle をインジェクトしフックを追加します。コンストラクタは素早く戻るべきです;長時間実行される作業は OnStart に属します。
func NewHTTPServer(lc fx.Lifecycle, log *zap.Logger, cfg *Config) *http.Server {
srv := &http.Server{Addr: cfg.Addr}
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
ln, err := net.Listen("tcp", srv.Addr)
if err != nil { return err }
go srv.Serve(ln) // ゴルーチン内でブロッキング処理を実行
return nil
},
OnStop: func(ctx context.Context) error {
return srv.Shutdown(ctx)
},
})
return srv
}
両方のコールバックは StartTimeout/StopTimeout で制限されたコンテキストを受け取ります — キャンセルを尊重してください。OnStart は素早く戻る必要があります — ブロッキング作業のためにゴルーチンを起動します;そうしないとスタートアップがハング依存フックが発火しません。
fx.StartHook / fx.StopHook / fx.StartStopHook はより単純なシグネチャ(コンテキストなし、エラーなし、または両方)を適応させます:
lc.Append(fx.StartStopHook(srv.Start, srv.Stop)) // マッチングペア
パラメータと結果オブジェクト
fx は dig の dig.In / dig.Out を fx.In / fx.Out として再エクスポートします。コンストラクタが 4 つ以上の依存関係を持つ場合、または name/group/optional タグが必要な場合に使用します。
type ServerParams struct {
fx.In
Logger *zap.Logger
DB *sql.DB
Cache *redis.Client `optional:"true"`
Routes []http.Handler `group:"routes"`
}
func NewServer(p ServerParams) *Server { /* ... */ }
fx.Annotate
fx.Annotate はコンストラクタをラップして fx.Out 構造体なしでタグまたはインターフェース バインディングを追加します。人間工学的な name/group/As バインディングの場合はこれを推奨します:
fx.Provide(
fx.Annotate(NewPrimaryDB, fx.ResultTags(`name:"primary"`)),
fx.Annotate(NewPostgresDB, fx.As(new(Database))), // インターフェースを公開
fx.Annotate(NewUserHandler,
fx.As(new(http.Handler)),
fx.ResultTags(`group:"routes"`),
),
)
値グループ
多くのコンストラクタ、1 つのコンシューマースライス — ルート、ヘルスチェック、メトリクスコレクタに典型的:
type RouteResult struct {
fx.Out
Handler http.Handler `group:"routes"`
}
type ServerParams struct {
fx.In
Routes []http.Handler `group:"routes"`
}
,flatten (group:"routes,flatten") を追加してスライスをネストする代わりにアンラップします。順序は 保証されません — シーケンスが重要な場合は明示的に順序付けされたスライスを提供します。
fx.Module
fx.Module はプロバイダー、invoke、デコレータを名前でグループ化します。モジュールは デコレータをスコープします — それ自体とその子供へ — fx.Module("db", ...) 内で名前が変更されたロガーはそのモジュール内のコードに対してのみ名前が変更されて表示されます。
var DatabaseModule = fx.Module("database",
fx.Provide(NewConnection, NewUserRepository),
fx.Decorate(func(log *zap.Logger) *zap.Logger {
return log.Named("db")
}),
)
func main() {
fx.New(
fx.Provide(NewConfig, NewLogger),
DatabaseModule,
HTTPModule,
).Run()
}
各モジュールを別のアプリに持ち上げられる小さなライブラリとして扱います — その公開サーフェスは提供する型です。
fx.Supply/fx.Replace/fx.Decorate、オプション依存関係、カスタムログ、手動ライフサイクル、クイックリファレンスについては advanced.md を参照してください。
ベストプラクティス
main()を薄く保つ — プロバイダー、モジュール、および単一のRun()。実際の作業をモジュールにプッシュして、各モジュールを分離してテスト可能にします。init()またはコンストラクタから起動したゴルーチンの代わりにライフサイクルフックを使用します — Start/Stop の順序はグラフトポロジーに依存しますが、init()ゴルーチンはそうではないため競合とリークが発生します。- OnStart は迅速に戻る必要があります — 長い作業はフック内のゴルーチンで実行します。ブロッキング OnStart はブートの残部をハングさせます。
- フック内で
ctx.Done()を尊重します — キャンセルを無視するフックはタイムアウト失敗として報告されますがそのゴルーチンは継続し、リソースをリークさせます。 - レイヤーではなくモジュールでグループ化します — モジュールは 1 つの関心事(HTTP、DB、メトリクス)のプロバイダー、ライフサイクル、デコレータを所有します。
- コンストラクタを
fx.Out構造体でラップするのではなくfx.Annotateをタグに使用します — コンストラクタを fx 外で再利用可能に保ちます。 - コンストラクタの代わりに
fx.Supplyを事前構築値(config、コマンドラインフラグ)に使用します。より短く、意図を示します。 - CI でグラフを検証します
fx.New(...).Err()でブートして — デプロイ前に欠落プロバイダーと循環を検出します。
一般的な間違い
| 間違い | 修正方法 |
|---|---|
| OnStart での長時間実行作業 | OnStart 内でゴルーチンを起動します;フック自体は素早く戻る必要があり、従属フックが実行できるようにします。 |
fx.Supply であるべき fx.Provide | 事前構築値(config、シークレット)は fx.Supply に属します — より明確でノーオップコンストラクタを回避します。 |
| モジュールデコレータが兄弟にリークする | fx.Module(...) 内でデコレートします — デコレータは子孫にのみ流れます。トップレベルの fx.Decorate はグローバルです。 |
| グループ順序を想定 | グループは順序なしです。順序が重要な場合、1 つのコンストラクタから順序付けされたスライスを提供します。 |
| サイドエフェクトを備えたコンストラクタ | サイドエフェクトは OnStart に属します — コンストラクタは安価で比較的純粋である必要があります、並行かつ遅延実行する可能性があるためです。 |
忘れた fx.Invoke | Invoke(または下流コンシューマー)がない場合、コンストラクタは実行されません。アプリごとに少なくとも 1 つの Invoke を追加します。 |
テスト
go.uber.org/fx/fxtest を使用して fx を *testing.T と統合します(失敗は t.Fatal を呼び出し、RequireStop は t.Cleanup として登録されます)。fx.Populate(&target) はグラフから値をプルします;fx.Replace は実際の依存関係をフェイクに交換します。完全なパターンは testing.md にあります。
さらに詳しく
advanced.md— Supply/Replace/Decorate、オプション依存関係、カスタムイベントログ、手動ライフサイクル、完全なクイックリファレンスrecipes.md— データベース/メトリクスを備えた完全な HTTP サービス、グレースフルドレイン付きバックグラウンドワーカー、同じインターフェースの複数実装、CLI 埋め込み用の手動ライフサイクルtesting.md— fxtest パターン、fx.Replace、fx.Populate、分離ライフサイクルテスト、CI グラフ検証
相互参照
- → 基礎となるコンテナ、
dig.In/dig.Out、ライフサイクルなしの DI についてはsamber/cc-skills-golang@golang-uber-digスキルを参照 - → DI の概念とライブラリ比較については
samber/cc-skills-golang@golang-dependency-injectionスキルを参照 - → リフレクションなしのジェネリクスベースの代替案については
samber/cc-skills-golang@golang-samber-doスキルを参照 - → コンパイル時 DI(実行時コンテナなし)については
samber/cc-skills-golang@golang-google-wireスキルを参照 - → インターフェース設計パターンについては
samber/cc-skills-golang@golang-structs-interfacesスキルを参照 - → OnStart/OnStop フック内のコンテキスト伝播については
samber/cc-skills-golang@golang-contextスキルを参照 - → 一般的なテストパターンについては
samber/cc-skills-golang@golang-testingスキルを参照
uber-go/fx でバグや予期しない動作が発生した場合、https://github.com/uber-go/fx/issues で issue を作成してください。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- samber
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/samber/cc-skills-golang / ライセンス: MIT
関連スキル
superfluid
Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。