Closed x80486 closed 1 year ago
As you yourself noted, this is a general impedance mismatch with Java. One thing you can do is make the fields Optional
. If I remember correctly, in that case you'd get an empty optional when an explicit null
is passed and null
when nothing was passed. I know this sounds backwards, but that's how all JSON libraries in Java (or at least the ones by default supported SPQR) decided to work.
It is not exactly pretty having Optional
all over, but I see now other way to generically solve this.
There is a somehow interesting implementation in the graphql-java-kickstart/graphql-java-tools
repository. I wouldn't like to have class members declared as Optional
, but if that works, I'll give it whirl for the time being 🙌🏻
It's interesting that this is not a hot subject in GraphQL (and typed languages) 🤔
Feel free to close this one if there is really nothing you could do in SPQR
to address that.
There's a few things to unpack here. Seems like you're trying to implement anemic mutations which are generally an anti-pattern in GraphQL. But you might have no other choice. Or maybe I'm just wrong and that's not what you're doing at all 😅
There's an alternative approach in SPQR that might be useful to you. If you deconstruct the input, e.g. instead of
@GraphQLQuery
public Book update(Book input) {...}
you have
@GraphQLQuery
public Book update(String title, Author author) {...}
and tell SPQR to generate Relay-compliant mutations:
generator.withRelayCompliantMutations()
SPQR will generate a specific input type for each mutation that doesn't already take a single object.
The Undefined
stuff you linked, is really a tri-state value, effectively like Optional
if you allow null
. But with a huge down side of being a custom type that has to pollute your domain model and needs custom handling for de/serialization.
I'm currently dealing with an old (really old) system where everything is quite loose (in terms of validations) and updates happen in a single workflow, hence the need for a big-bloated object with optional members. On the other hand, while you can work with aggregates on the border, it's not really useful since they tend to have more fields/members than those models (you name it: DTOs, etc.) you use for input data. In that sense, I don't find Undefined
as a pretty bad design, because it's something that's used on the border, and propagated into proper domain models later.
I'm just introducing a way to have an API, and probably modernize the user interface at some point.
I'll definitely check that approach with generator.withRelayCompliantMutations()
also 👍🏻
I'm currently using
GraphQL SPQR
with the Spring Boot starter. I'm trying to find a way to support partial updates using the same (domain model) class, but I can't find a way to make it work.Basically, what I'm trying to do is to have a class that's used for updates to a given model:
So far, if I would like to use the same class for partial updates, I can't tell which value between
status
and/orversion
is meant to be updated becausenull
doesn't really help there. I can't assume that the presence ofnull
is just the fact that the field in question is going to be reset (as in unset) to back tonull
or just not updated.