Parameter Objects¶
A parameter object is an objects with the sole purpose of carrying parameters for a specific function or method.
The object is typically defined exclusively for that function,
and is not shared with other functions.
That is, a parameter object is not a general purpose object like "user"
but purpose-built, like "parameters for the GetUser
function".
In Fx, parameter objects contain exported fields exclusively,
and are always tagged with fx.In
.
Related
- Result objects are the result analog of parameter objects.
Using parameter objects¶
To use parameter objects in Fx, take the following steps:
-
Define a new struct type named after your constructor with a
Params
suffix. If the constructor is namedNewClient
, name the structClientParams
. If the constructor is namedNew
, name the structParams
. This naming isn't strictly necessary, but it's a good convention to follow.type ClientParams struct { }
-
Embed
fx.In
into this struct.type ClientParams struct { fx.In
-
Add this new type as a parameter to your constructor by value.
func NewClient(p ClientParams) (*Client, error) {
-
Add dependencies of your constructor as exported fields on this struct.
type ClientParams struct { fx.In Config ClientConfig HTTPClient *http.Client }
-
Consume these fields in your constructor.
func NewClient(p ClientParams) (*Client, error) { return &Client{ url: p.Config.URL, http: p.HTTPClient, // ... }, nil
Once you have a parameter object on a function, you can use it to access other advanced features of Fx:
Adding new parameters¶
You can add new parameters for a constructor by adding new fields to a parameter object. For this to be backwards compatible, the new fields must be optional.
-
Take an existing parameter object.
type Params struct { fx.In Config ClientConfig HTTPClient *http.Client } func New(p Params) (*Client, error) {
-
Add a new field to it for your new dependency and mark it optional to keep this change backwards compatible.
type Params struct { fx.In Config ClientConfig HTTPClient *http.Client Logger *zap.Logger `optional:"true"` }
-
In your constructor, consume this field. Be sure to handle the case when this field is absent -- it will take the zero value of its type in that case.
func New(p Params) (*Client, error) { log := p.Logger if log == nil { log = zap.NewNop() } // ...