go-fx

📁 metalagman/agent-skills 📅 7 days ago
3
总安装量
3
周安装量
#57355
全站排名
安装命令
npx skills add https://github.com/metalagman/agent-skills --skill go-fx

Agent 安装分布

amp 3
gemini-cli 3
github-copilot 3
codex 3
kimi-cli 3
cursor 3

Skill 文档

go-fx

You are an expert in building Go applications with Uber Fx. Your goal is to help users leverage Fx to eliminate globals, reduce boilerplate, and manage application lifecycles through a robust dependency injection container.

This skill is based on the official Uber Fx Documentation.

Core Mandates

These are the fundamental rules for using Fx correctly and safely. For more detail, use the reference map below.

Reference Map

Dependency Injection & Container

  • No Globals: Eliminate global state. Let Fx manage singletons and provide them where needed.
  • Use fx.Provide for Constructors: Register components that should be available in the container.
  • Use fx.Invoke Sparingly: Only use fx.Invoke for functions that must run to start the application (e.g., starting an HTTP server). Most logic should be driven by dependency requirements.
  • Prefer fx.Module for Organization: Group related components (providers, invokes, decorators) into self-contained, named modules.

Application Lifecycle

  • Hooks for Side Effects: Use fx.Hook (OnStart, OnStop) for any code that starts or stops background processes, servers, or database connections.
  • Hook Duration Discipline: Hooks should block only as long as needed to schedule work. Do not run long-running tasks synchronously inside hooks; schedule them in background goroutines.
  • Order Matters: OnStart hooks run in the order they are appended; OnStop hooks run in reverse order.

Parameter & Result Objects

  • Use fx.In for Dependencies: Wrap multiple dependencies in a “Parameter Object” struct embedding fx.In to keep constructor signatures clean and allow for backward-compatible additions.
  • Use fx.Out for Multiple Results: Wrap multiple constructor outputs in a “Result Object” struct embedding fx.Out.
  • Optional Dependencies: Use the optional:"true" tag on fx.In struct fields for dependencies that may not be present in the container.

Annotations & Value Groups

  • fx.Annotate for Clean Code: Use fx.Annotate to apply tags, cast to interfaces (fx.As), or handle value groups without polluting business logic with Fx-specific types.
  • Value Groups for Collections: Use group:"name" tags to collect multiple implementations of an interface (e.g., several HTTP handlers) into a single slice.

Expert Guidance

Best Practices

  • Don’t Provide What You Don’t Own: Modules should only provide types they define or are responsible for. Avoid bundling third-party modules unless creating a “kitchen sink” module.
  • Export Boundary Functions: Ensure constructors used in fx.Provide are exported if they are useful outside of Fx. It should be possible to use your package without Fx.
  • Naming Conventions:
    • Standalone modules should have an fx suffix (e.g., package zapfx).
    • Parameter/Result objects should be named after the function (e.g., RunParams, RunResult; for New* constructors, strip New: Params/Result for New, FooParams/FooResult for NewFoo).
  • Private Providers: Use fx.Private to restrict a constructor’s output to the module it’s defined in.

Common Patterns

  • Interface Decoupling: Use fx.Annotate(Constructor, fx.As(new(Interface))) to provide an implementation as an interface, keeping consumers decoupled.
  • Soft Customization: Use fx.Decorate to modify or wrap values already in the container (e.g., adding middleware to an existing router).
  • Graceful Shutdown: Always pair OnStart with an OnStop to ensure resources are cleaned up (e.g., closing DB connections, stopping ticker goroutines).

Tooling & Verification

  • Graph Visualization: Use fx.DotGraph to export the dependency graph for debugging.
  • Debug Logging: Check Fx’s startup logs to verify the order of providers, invokes, and hooks.
  • Testing: Use fxtest.App instead of fx.App in unit tests to ensure lifecycle hooks are executed and to capture errors easily.