trustfall icon indicating copy to clipboard operation
trustfall copied to clipboard

Support for `@optional` and sibling fields on type coercion

Open ginger51011 opened this issue 1 year ago • 4 comments

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?

ginger51011 avatar Apr 19 '23 15:04 ginger51011

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] where Photo implements File).
  • 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.

obi1kenobi avatar Apr 19 '23 16:04 obi1kenobi

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)

ginger51011 avatar Apr 19 '23 16:04 ginger51011

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

ginger51011 avatar Apr 19 '23 17:04 ginger51011

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.

obi1kenobi avatar Apr 19 '23 17:04 obi1kenobi