Skip to content

Preserve property shape when parent is null #424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
tkers opened this issue Jul 7, 2016 · 1 comment
Closed

Preserve property shape when parent is null #424

tkers opened this issue Jul 7, 2016 · 1 comment

Comments

@tkers
Copy link

tkers commented Jul 7, 2016

Maybe slightly related to #421, but from the client's perspective rather than enforcing the field inclusion from the server side.

I noticed leebyron stating:

I don't think this is a good idea since it reduces a client's ability to predict the shape of the response

For an issue I recently ran into; how about including (nullable) fields that the client specifically requests? This is especially relevant for fields that have a specific type/shape defined, it feels a bit weird that the parent property can be omitted completely.

e.g. we have a nested profile.settings.someValue property, where we explicitly define the profileType to contain a settingsType, and explicitly list all the keys in the settingsType (rather than just using a generic object type). Now, whenever the database fetches a resource where profile.settings is not (yet) defined (maybe new profiles that have no explicit values set for the keys yet), settings will be omitted completely. This causes a query for profile { settings { someValue } } to not return anything, leaving the client to handle checking if the full tree of (sub)properties exists.

A way to solve this at the moment is to provide a default value { } for settings, or making sure that the underlying database has all fields properly defined to begin with, but to me this felt a bit awkward.

Is it possible to make sure the shape of the object is preserved even when all the leaf-values are null? Or would this be too language-specific or even conceptually not making sense to do?

@leebyron
Copy link
Contributor

leebyron commented Jul 19, 2016

I think this does not make conceptual sense.

For example, consider the query:

{ me { favoriteColor } }

These two responses actually reflect different semantic values:

{ me: null }
{ me: { favoriteColor: null } }

The first might indicate that there's no logged in user. The second might indicate that there is a logged in user, but they happen to not have a favorite color.

If we were to replace null values with objects filled with null keys, then interpreting the difference between the two semantic values would be impossible.

There's also a problematic case where the leaf field is non-nullable. Consider requesting a location when there isn't one available:

{ location: { lat: null, lon: null }}

This might be an illegal value if a location is defined as non-nullable lat and lon. Would you expect to instead receive { location: {} }? I think that would be a more confusing result than { location: null } in addition to violating the notion that a field queried will be contained in the response - no empty object like that should exist in any GraphQL response.

Handling intermediate nulls (or empty Maybes) in a programming language is a problem much bigger than GraphQL. I understand that the desire to write a.b.c when a.b could be null can be frustrating, but that's our reality with any data-backed API.

See some other discussion on this topic: https://esdiscuss.org/topic/the-existential-operator

Closing the issue, but feel free to discuss further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants