# The quasi-directive @genqlient is used to configure genqlient on a # query-by-query basis. # # The syntax of the directive is just like a GraphQL directive (as defined # below), except it goes in a comment on the line immediately preceding the # field. (This is because GraphQL expects directives in queries to be defined # by the server, not by the client, so it would reject a real @genqlient # directive as nonexistent.) # # Directives may be applied to fields, arguments, or the entire query or named # fragment. Directives on the line preceding the query or a named fragment # apply to all relevant nodes in the query; other directives apply to all nodes # on the following line. (In all cases it's fine for there to be other # comments in between the directive and the node(s) to which it applies.) For # example, in the following query: # # @genqlient(n: "a") # # # @genqlient(n: "b") # # # # Comment describing the query # # # # @genqlient(n: "c") # query MyQuery(arg1: String, # # @genqlient(n: "d") # arg2: String, arg3: MyInput, # arg4: String, # ) { # # @genqlient(n: "e") # field1, field2 # # @genqlient(n: "f") # field3 { # field4 # } # } # the directive "a" is ignored, "b" and "c" apply to all relevant nodes in the # query, "d" applies to arg2 and arg3, "e" applies to field1 and field2, and # "f" applies to field3. # # Except as noted below, directives on nodes take precedence over ones on the # entire query (so "d", "e", and "f" take precedence over "b" and "c"), and # multiple directives on the same node ("b" and "c") must not conflict. Note # that directives on nodes do *not* apply to their "children", so "d" does not # apply to the fields of MyInput, and "f" does not apply to field4. (But # directives on operations and fragments do: both "b" and "c" apply to fields # of MyInput and to field4.) directive genqlient( # If set to a string "MyType.myField", this entire @genqlient directive # will be treated as if it were applied to the specified field of the # specified type. It must be applied to an entire operation or fragment. # # This is especially useful for input-type options like omitempty and # pointer, which are equally meaningful on input-type fields as on arguments, # but there's no natural syntax to put them on fields. # # Note that for input types, unless the type has the "typename" option set, # all operations and fragments in the same package which use this type should # have matching directives. (This is to avoid needing to give them more # complex type-names.) This is not currently validated, but will be # validated in the future (see issue #123). # # For example, given the following query: # # @genqlient(for: "MyInput.myField", omitempty: true) # # @genqlient(for: "MyInput.myOtherField", pointer: true) # # @genqlient(for: "MyOutput.id", bind: "path/to/pkg.MyOutputID") # query MyQuery( # $arg: MyInput # ) { ... } # genqlient will generate a type # type MyInput struct { # MyField `json:"myField,omitempty"` # MyOtherField * `json:"myField"` # MyThirdField `json:"myThirdField"` # } # and use it for the argument to MyQuery, and similarly if `MyOutput.id` is # ever requested in the response, it will be set to use the given type. for: String # If set, this argument (or input-type field, see "for") will be omitted if # it has an empty value, defined (the same as in encoding/json) as false, 0, # a nil pointer, a nil interface value, and any empty array, slice, map, or # string. # # For example, given the following query: # # @genqlient(omitempty: true) # query MyQuery($arg: String) { ... } # genqlient will generate a function # MyQuery(ctx context.Context, client graphql.Client, arg string) ... # which will pass {"arg": null} to GraphQL if arg is "", and the actual # value otherwise. # # Only applicable to arguments of nullable types. Ignored for types with # custom marshalers (see their documentation in genqlient.yaml for details). omitempty: Boolean # If set, this argument or field will use a pointer type in Go. Response # types always use pointers, but otherwise we typically do not. # # This can be useful if it's a type you'll need to pass around (and want a # pointer to save copies) or if you wish to distinguish between the Go # zero value and null (for nullable fields). pointer: Boolean # If set, this field will use a struct type in Go, even if it's an interface. # # This is useful when you have a query like # query MyQuery { # myInterface { myField } # } # where you are requesting only shared fields of an interface. By default, # genqlient still generates an interface type, for consistency. But this # isn't necessary: a struct would do just fine since there are no # type-specific fields. Setting `struct: true` tells genqlient to do that. # # Note that this is only allowed when there are no fragments in play, such # that all fields are on the interface type. Note that if you later add a # fragment, you'll have to remove this option, and the types will change. struct: Boolean # If set, this field's selection must contain a single fragment-spread; we'll # use the type of that fragment-spread as the type of the field. # # For example, given a query like # query MyQuery { # myField { # ...MyFragment # } # } # by default genqlient will generate these types: # type MyQueryResponse struct { # MyField MyQueryMyFieldMyType # } # type MyQueryMyFieldMyType struct { # MyFragment # } # If we instead do: # query MyQuery { # # @genqlient(flatten: true) # myField { # ...MyFragment # } # } # genqlient will simplify things: # type MyQueryResponse struct { # MyField MyFragment # } # # This is only applicable to fields whose selection is a single # fragment-spread, such that the field-type implements the fragment-type # (i.e. we can't do this if MyFragment is on one implementation of the type # of MyField; what if we got back the other type?). flatten: Boolean # If set, this argument or field will use the given Go type instead of a # genqlient-generated type. # # The value should be the fully-qualified type name to use for the field, # for example: # time.Time # map[string]interface{} # []github.com/you/yourpkg/subpkg.MyType # Note that the type is the type of the whole field, e.g. if your field in # GraphQL has type `[DateTime]`, you'd do # # @genqlient(bind: "[]time.Time") # (But you're not required to; if you want to map to some type DateList, # you can do that, as long as its UnmarshalJSON method can accept a list # of datetimes.) # # Note that the type you bind to must be defined elsewhere in your code. # If you want genqlient to create the type definition, use "typename" # instead. # # See bindings in genqlient.yaml for more details; this is effectively to a # local version of that global setting and should be used with similar care. # If set to "-", overrides any such global setting and uses a # genqlient-generated type. bind: String # If set, the type of this field will have the given name in Go. # # For example, given the following query: # # @genqlient(typename: "MyResp") # query MyQuery { # # @genqlient(typename: "User") # user { # id # } # } # genqlient will generate # type Resp struct { # User User # } # type User struct { # Id string # } # instead of its usual, more verbose type names. # # You may also use "typename" on basic types, and Go will create a # type definition for that basic type. For instance: # query MyQuery { # user { # # @genqlient(typename: "NameType") # name # } # } # will cause gnqlient to generate: # type Resp struct { # User User # } # type NameType string # type User struct { # Name NameType # } # (Compare this to @genqlient(bind: "path/to/pkg.NameType"), which does # something similar but depends on "NameType" being defined in some # other package, rather than having genqlient define it for you.) # # With great power comes great responsibility: when using typename you'll # need to avoid comments; genqlient will complain if you use the same # type-name in multiple places unless they request the exact same fields, or # if your type-name conflicts with an autogenerated one (again, unless they # request the exact same fields). They must even have the fields in the # same order. They should also have matching @genqlient directives, although # this is not currently validated (see issue #123). Fragments are often # easier to use (see the discussion of code-sharing in FAQ.md, and the # "flatten" option above). # # Note that unlike most directives, if applied to the entire operation, # typename affects the overall response type, rather than being propagated # down to all child fields (which would cause conflicts). # # To avoid confusion, typename may not be combined with local or global # bindings; to use typename instead of a global binding do # `typename: "MyTypeName", bind: "-"`. typename: String # Multiple genqlient directives are allowed in the same location, as long as # they don't have conflicting options. ) repeatable on # genqlient directives can go almost anywhere, although some options are only # applicable in certain locations as described above. | QUERY | MUTATION | SUBSCRIPTION | FIELD | FRAGMENT_DEFINITION | VARIABLE_DEFINITION