c6d087c29b
## Summary:
One common use of fragment spreads is as the entirety of a field's
selection, e.g.
```graphql
query MyQuery {
myField {
...MyFragment
}
}
```
In this case, by default, genqlient generates a wrapper type
`MyQueryMyFieldMyType`, which just embeds `MyFragment`. This makes
sense if you later want to add more fields in addition to the fragment
spread. But if you don't -- and you did the fragment because you want
to share types, it's an extra layer of indirection. (Which becomes
especially onerous if `myField` has list type (`[MyType!]`), such that
it's not just an extra attribute-access to get to `MyFragment`.)
The new option `# @genqlient(flatten: true)` simplifies this situation:
if applied to `myField` is skips the wrapper type;
`MyQueryResponse.MyField` will simply have type `MyFragment` (or
`[]MyFragment`, or whatever). This should hopefully make the `typename`
option, which has more limitations, less necessary.
Note that in #30 the initial idea was to support this for fields as
well. This would require significant additional complexity in the
JSON-(un)marshaling code, and has proven less necessary, so I
implemented this option only for fragment-spreads for now. With that
restriction, it was shockingly simple; we have to hook into a bunch of
different places, but they're all quite simple, since the structure of
the Go types still matches the structure in GraphQL.
Issue: https://github.com/Khan/genqlient/issues/30
## Test plan:
make check
Author: benjaminjkraft
Reviewers: csilvers, dnerdy, aberkan, jvoll, mahtabsabet, MiguelCastillo, StevenACoffman
Required Reviewers:
Approved By: csilvers, dnerdy
Checks: ✅ Test (1.17), ✅ Test (1.16), ✅ Test (1.15), ✅ Test (1.14), ✅ Lint, ✅ Test (1.17), ✅ Test (1.16), ✅ Test (1.15), ✅ Test (1.14), ✅ Lint
Pull Request URL: https://github.com/Khan/genqlient/pull/121
2.9 KiB
2.9 KiB
Changelog
next
Breaking changes:
New features:
- genqlient's types are now safe to JSON-marshal, which can be useful for putting them in a cache, for example. See the docs for details.
- The new
flattenoption in the# @genqlientdirective allows for a simpler form of type-sharing using fragment spreads. See the docs for details.
Bug fixes:
v0.2.0
Version 0.2.0 adds several convenience features for using custom scalars, as well as many internal improvements and bug fixes.
Breaking changes:
- The
graphql.Clientinterface now acceptsvariables interface{}(containing a JSON-marshalable value) rather thanvariables map[string]interface{}. Clients implementing the interface themselves will need to change the signature; clients who simply callgraphql.NewClientare unaffected. - genqlient's handling of the
omitemptyoption has changed to match that ofencoding/json, from which it had inadvertently differed. In particular, this means struct-typed arguments with# @genqlient(omitempty: true)will no longer be omitted if they are the zero value. (Struct-pointers are still omitted if nil, so addingpointer: truewill typically work fine. It's also now possible to use a custom marshaler to explicitly map zero to null.)
New features:
- The new
bindings.marshalerandbindings.unmarshaleroptions ingenqlient.yamlallow binding to a type without using its standard JSON serialization; see the documentation for details. - Multiple genqlient directives may now be applied to the same node, as long as they don't conflict; see the directive documentation for details.
Bug fixes:
- The
omitemptyoption now works correctly for struct- and map-typed variables, matchingencoding/json, which is to say it never omits structs, and omits empty maps. (#43) - Generated type-names now abbreviate across multiple components; for example if the path to a type is
(MyOperation, Outer, Outer, Inner, OuterInner), it will again be calledMyOperationOuterInner. (This regressed in a pre-v0.1.0 refactor.) (#109) - Previously, interface fields with
# @genqlient(pointer: true)would be unmarshaled to(*MyInterface)(*<nil>), i.e. a pointer to the untyped-nil of the interface type. Now they are unmarshaled as(*MyInterface)(<nil>), i.e. a nil pointer of the pointer-to-interface type, as you would expect.
v0.1.0
First open-sourced version.