Skip to content
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

Null and omitted attributes in InputObjects #112

Closed
guigrpa opened this issue Aug 8, 2015 · 6 comments
Closed

Null and omitted attributes in InputObjects #112

guigrpa opened this issue Aug 8, 2015 · 6 comments

Comments

@guigrpa
Copy link

guigrpa commented Aug 8, 2015

I want to build a mutation to modify (let's be original) a ToDo object. My hypothetical ToDo object has three fields: whatToDo, notes and assignee, all of them GraphQLStrings. So I define an InputObject type with all three fields:

ToDoInput = new GraphQLInputObjectType
  name: 'ToDoInput'
  fields: -> # all of them nullable
    whatToDo: type: GraphQLString
    notes:    type: GraphQLString
    assignee: type: GraphQLString

My generic mutation will be like this:

UpdateToDoMutation = new GraphQLObjectType
  type: ToDo
  args:
    id:    type: new GraphQLNonNull GraphQLID
    attrs: type: ToDoInput
  resolve: -> # ...

Now let's assume I want to use this new mutation to do the following: "update the whatToDo field and set the assignee field to null, leaving the rest (notes) unchanged". I would love to write...

mutation M {    // [incorrect GraphQL]
  updateToDo(id: 3, attrs: {whatToDo: 'whatever', assignee: null}) { ... }
}

...that is: explicitly including assignee: null to nullify that attribute, and omitting notes to leave this attribute as it is. But unfortunately the spec (and @leebyron's Slack remark confirms it) says null values can only be modeled by leaving the attribute out, colliding with my other semantic needs: omitting an attribute to just not touch it.

Any chance the spec might support null as a valid literal value? (Otherwise: what other options are there to implement such a generic mutation?).

@will-weiss
Copy link

Perhaps you could accomplish this using

UpdateToDoMutation = new GraphQLObjectType
  type: ToDo
  args:
    id:    type: new GraphQLNonNull GraphQLID
    set: type: ToDoInput
    unset: type: new GraphQLList(GraphQLString)
  resolve: (root, args)->   # ...

then you could write:

mutation M {
  updateToDo(id: 3, set: {whatToDo: 'whatever'}, unset: ['assignee'] { ... }
}

achieving the desired goal within the bounds of the language specification.

@leebyron
Copy link
Contributor

The primary issue here is that most environments do not distinguish between null and undefined in the way JavaScript does. Since GraphQL is designed to be a thin layer atop many different environments, we can't always support the distinction.

I think @will-weiss's suggestion is closer to what you want. To explicitly declare the things you are removing in a mutation.

@leebyron
Copy link
Contributor

One change that I can make that should make working with APIs that treat null specially is to also omit the not set object properties on the internal value.

@guigrpa
Copy link
Author

guigrpa commented Aug 11, 2015

Yes, the workaround is really nice. I got it going without problems, thanks a lot for the idea. Regarding the reason behind the spec, I understand better now - but it's a pity I can't use a cleaner API considering that I have JS on both client and server.

On Tue, Aug 11, 2015 at 10:23 PM, Lee Byron notifications@github.com
wrote:

One change that I can make that should make working with APIs that treat null specially is to also omit the not set object properties on the internal value.

Reply to this email directly or view it on GitHub:
#112 (comment)

@leebyron
Copy link
Contributor

2734d01 and 44c9daf implement the change that omits properties from arguments and input objects that were not provided, rather than their previous behavior of being set to null.

Hopefully this change will help when being paired with APIs which treat null differently from undefined.

@leebyron
Copy link
Contributor

These changes will go out in the next version release.

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

3 participants