zino-hofmann / graphql-flutter

A GraphQL client for Flutter, bringing all the features from a modern GraphQL client to one easy to use package.
https://zino-hofmann.github.io/graphql-flutter
MIT License
3.25k stars 620 forks source link

undefined input variable #1138

Closed manlyman29 closed 2 years ago

manlyman29 commented 2 years ago

Describe the issue It looks like when converting a class to json (Map<String, dynamic) library knows only defined and null. There is an undefined state that most GraphQL clients implement somehow.

To Reproduce (MUST BE PROVIDED)

Let's say we have a mutation input object with two nullable variables: status & description. This is how object is created and transformed into json:

runMutation(UpdateOrderArguments(
  id: state.order.id,
  update: UpdateOrderInput(status: OrderStatus.canceled)).toJson())

The toJson() will create a Map with description being set to null and this will lead to unexpected behavior because the server will assume that we want to set the description to null. In UpdateOrderInput, description argument wasn't passed so the resulted Map shouldn't have description at all.

I think the default behavior for null fields should be undefined. For passing actual nulls a wrapped object allowing null being passed can be created. This is how Apollo has done this in their Kotlin client for example. As far as i see it the current design can lead to lots of unexpected bugs/behaviors with a simple api change.

Expected behavior Only converts the passed arguments not all of them.

device / execution context Behavior is same on all environments.

additional context

additional notes Did you struggle to understand the docs or examples, or dislike the current api?

budde377 commented 2 years ago

This should be implemented by the serialiser you're using. If we implement this on the client framework we'll not be able to express null and undefined behaviour.

budde377 commented 2 years ago

To elaborate a bit on the response.

Currently, you can express the null and undefined behavior with the maps

{"description": null} // set to null
{} // description is undefined

Variables and input objects are all maps and the library intentionally does not generate any serializers for these. Thus, you'll need to make sure that your serializers generate the correct type of map. If you're using GraphQL codegen, you can strip null fields from input types: https://pub.dev/packages/graphql_codegen#strip-null-from-input-serializers.

manlyman29 commented 2 years ago

Thanks, you are right about this requires to be fixed from the generator or serializer library side. For a moment i forgot that these two packages are separate. sorry.