Files
genqlient/docs/genqlient_directive.graphql
Matúš Bafrnec 00f27609f0 fixed "for" directive documentation (#235)
This PR is addressing the behavior described in #151.
The former version of `for` directive example usage ended in:
```
genqlient.graphql:<line>: for is only applicable to operations and arguments
```


I have:
- [x] Written a clear PR title and description (above)
- [x] Signed the [Khan Academy CLA](https://www.khanacademy.org/r/cla)
- [x] Added tests covering my changes, if applicable
- [x] Included a link to the issue fixed, if applicable
- [x] Included documentation, for new features
- [x] Added an entry to the changelog

Signed-off-by: Matúš Bafrnec <matus.bafrnec@gmail.com>
2022-11-17 18:19:35 -05:00

248 lines
9.5 KiB
GraphQL

# 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 <type> `json:"myField,omitempty"`
# MyOtherField *<type> `json:"myField"`
# MyThirdField <type> `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