trustfall
trustfall copied to clipboard
Support for `@optional` and sibling fields on type coercion
I have some issues with some of my queries failing because their type coercion cannot be marked as @optional
, and also because they cannot have sibling fields (both are defined in the specs).
The current behavior seems to match that of GraphQL compiler, but is there any plans to update this behaviour?
Currently I see no other option than to have multiple queries to not fail based on a coercion not working, but perhaps my queries are wrong?
Unfortunately, I don't have a concrete timeline to offer. Appropriately prioritizing between the various ways to expand query functionality (e.g. this, #83, more @transform
kinds, etc.) is a challenge and I need more community input so I know what's important.
There are several workarounds available in the meantime, and which is most appropriate is a function of your specific queries and use case:
- Having multiple queries is certainly an option, but seldom the best option.
- Tweaking the edges exposed in the schema is usually better. Instead of "generic edge + type coercion" (e.g.
attachment: [File]
you may be able to expose one or more "specific edges with an implicit coercion" (e.g.attached_photo: [Photo]
wherePhoto
implementsFile
). - Sometimes, it may also be feasible to replace this functionality with a post-filtering step after getting the data from Trustfall: instead of applying an optional type coercion, add
__typename @output
to the query and apply the appropriate logic to the result afterward.
Also, as you've found, the spec outlines the desired semantics but isn't fully implemented. We need to document this fact better, and I'd welcome PRs to that effect.
Very reasonable, thanks for the suggested workarounds! This isn't a show-stopper for me, but it is a nice functionality, at least for me.
#83 also looks very desirable for my purposes, so I completely understand that your time is limited (unfortunately, so is mine)
Related to this (but perhaps not?), adding @optional
to the field being type coerced also does not work, but perhaps this has something to do with how optional works (not applying to inner fields in this way)?
I mean
someUnrelatedData @output
someField @optional {
... on somethingElse {
id @output
}
}
produces an empty list instead of the unrelated data like I expect
Yes, I suspect this is indeed related to how @optional
works: it only makes the edge optional and doesn't go any deeper. If the edge is resolved and found to exist, the remainder of the query proceeds same as if the edge weren't @optional
at all.
In other words, the semantics don't allow "pretending the edge didn't exist" if an optional edge did exist but failed to satisfy a subsequent filter or type coercion. That's a semantically different operation that's much broader than the edge, and can be partially emulated with a @fold @transform(op: "count") @filter(op: ">", value: ["$zero"])
on the edge instead. I say "partially" because it also ends up aggregating the results on the edge, whether or not that was actually preferable. This is in turn a symptom of another missing directive — perhaps named @unfold
.