Replies: 1 comment
-
I am sure we can support this in SmallRye. 1) we can put more effort into supporting Unions. 2) Wrapping in a Result is king of already possible (You just need to write the Result object yourself). Can we abstract that automatically ? Maybe, we have to find a nice way to know what to respond, the wrapped Result or the initial object... How about a PR ? Then we talk through it. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I have a more advanced topic that I'd like to discuss with you. I hope you can find the time to read it. Maybe watching the excellent talk by Sasha Solomon is a good start to get into the topic, then you can skip some of this.
I plan to write a blog post about this, but before I do that, I'd like to discuss the last point with you, as we might need a change to SmallRye GraphQL in order to make this just the perfect solution.
Context
We currently report all errors via the same, basic GraphQL errors mechanism, often with a
code
extension field to distinguish different error situations. Our customers repeatedly asked us for the list of all possible error code values, which we do not want to supply, as this is a one-way and out-of-band communication. We prefer to have the clients instead express what they actually need: we want to understand the use-cases of our clients, also when they need to react to certain business error conditions, e.g. when an order is locked or can't be found. The GraphQL schema provides other, better suited, ways to inform clients about business error situations:Unions
The valid response value and all possible business errors can be combined into a Union, so only one can be set.
The schema could be:
The
positive
field is just a dummy value that is alwaystrue
; we define it, as a type must have at least one field, but we definitively want it to be an object, so we can add other fields later.A query could be:
Interfaces
As SmallRye GraphQL currently doesn't support Unions (see #400), GraphQL Interfaces can be used as a trick, which result in exactly the same queries:
The
positive
field in the interface correspond to thepositive
field in the Union solution above, but an interface has to have at least one field itself, so it's inherited by all implementations. (It would be nice if SmallRye GraphQL would support it to be adefault
method, but that's a different issue).Error Fields
The Union based solution is great (and the Interface trick is an okayish workaround): the schema clearly documents what possibly can go wrong business-wise. But it doesn't mitigate one major problem: the backend still doesn't see which clients need to handle which errors, as they can react to any of the possible
__typename
values without selecting even a single detail field: the__typename
is still just the newcode
extension. Among other things, this means that the backend can't see that some error is not needed any more and could be removed.An alternative to make the clients' requirements visible is that the
OrderResult
is a regular wrapper type where exactly one field is set (the Java class would have to make sure):If an error situation arises that a client didn't select, e.g. she doesn't know an order can be locked, we fall back to the classic
errors
field, preventing the situation that all fields arenull
and the client has no idea why.If an error field applies to a deeply nested value, the error type can contain a path (similar to the
errors
), e.g. anInvalidZipCode
type could have apath
array field containing["order", "customer", "address"]
.At any time, we can add a new error field to inform clients about a new situation; existing clients will get those errors in the 'old' way. If clients want to react to a certain situation, they can simply select the corresponding error field.
If we see that no client selects an error field any more, we can safely remove the field.
Conclusion
All is well? Not exactly. We loose one feature that I love so dearly about the MP GraphQL approach: directly use standard Java mechanisms, i.e. simply return my
Order
object and do the error handling via exceptions. This elegance is lost by this solution. I'll have to jump several extra loops to make this work.So here is my question: could we add support for this approach directly to SmallRye GraphQL? I.e. some way to configure return types to be wrapped in
Result
types and map the exceptions accordingly? What do you think?!?Beta Was this translation helpful? Give feedback.
All reactions