Add support for specifying type-names, and conflict-detection (#94)
## Summary: In this commit I add two related features to genqlient: conflict-detection to avoid generating two distinct types with the same name, and an option to specify the type-name genqlient should use for some type. The conflict-detection was pretty simple once I realized I had already written all the code to do it in #70. There was a bunch of wiring, since we now need to keep track of the GraphQL type/selection-set that each type corresponds to, but it was pretty straightforward. This allows us to: - detect and reject if you have really sneaky type-names (there are some examples documented in `names.go`) - more clearly crash if genqlient accidentally generates two conflicting types, and - avoid stack-overflow when handing recursive (input) types (although sadly the poor support for options on input types (#14) makes them difficult to use in many cases; you really need to be able to set `pointer: true`) And with that all set up, the type-naming was also easy! (It doesn't have to get into the core of the type-generator, just plug in where we choose names. The desire for conflict detection was the main reason I hadn't set it up already.) Note that the existing limitation of #70 that the fields have to be in exactly the same order remains (and is now documented as #93); it's not deeply hard to fix but it's surprisingly much work. Issue: https://github.com/Khan/genqlient/issues/60 Issue: https://github.com/Khan/genqlient/issues/12 ## Test plan: make check Author: benjaminjkraft Reviewers: StevenACoffman, jvoll, benjaminjkraft, aberkan, csilvers, dnerdy, mahtabsabet, MiguelCastillo Required Reviewers: Approved By: StevenACoffman, jvoll 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/94
This commit is contained in:
@@ -91,6 +91,38 @@ directive genqlient(
|
||||
# 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.
|
||||
#
|
||||
# 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. Fragments are often easier to use (see the discussion of
|
||||
# code-sharing in FAQ.md).
|
||||
#
|
||||
# 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).
|
||||
typename: String
|
||||
|
||||
) on
|
||||
# genqlient directives can go almost anywhere, although some options are only
|
||||
# applicable in certain locations as described above.
|
||||
|
||||
Reference in New Issue
Block a user