gql-dart / ferry

Stream-based strongly typed GraphQL client for Dart
https://ferrygraphql.com/
MIT License
593 stars 113 forks source link

Cannot use `tristate_optionals: true` in mutations having lists in their parameters #571

Open KevinDespoulainsTR opened 6 months ago

KevinDespoulainsTR commented 6 months ago

Hi!

I found an issue when using the tristate_optionals: true option in ferry_generator|graphql_builder.

I forked the project and updated the pokemon_explorer example to show you how to easily reproduce the issue.

What I have done :

input PokemonUpdateInput { id: Int! name: String! }

- Created a `update_pokemon.graphql` file under the `src/graphql/` folder containing the following code : 

mutation UpdatePokemons($pokemons: [PokemonUpdateInput!]) { updatePokemons(pokemons: $pokemons) }


Here, if you run the `dart run build_runner build --delete-conflicting-outputs`,  everything is working as expected 👌 

Now, if you add the `tristate_optionals: true` to the `build.yaml` file : 

targets: $default: builders: ferry_generator|graphql_builder: enabled: true options: schema: pokemon_explorer|lib/schema.graphql tristate_optionals: true when_extensions: when: true maybeWhen: true ferry_generator|serializer_builder: enabled: true options: schema: pokemon_explorer|lib/schema.graphql

And run the `dart run build_runner build --delete-conflicting-outputs` command, the `serializes.gql.g.dart` file is missing the following builder factory : 

... ..addBuilderFactory( const FullType( BuiltList, const [const FullType(GPokemonUpdateInput)]), () => new ListBuilder()) ...


Therefore, when the code is running and the `GPokemonUpdateInput` needs to be serialized, there is an exception indicating that no serializer is found for the `BuiltList<GPokemonUpdateInput>`. 

StateError (Bad state: No builder factory for BuiltList. Fix by adding one, see SerializersBuilder.addBuilderFactory.)


If you turn `off` the `tristate_optionals`, the builder factory is added as expected and the code is running perfectly (but the tristate feature cannot be used).

Is there anything missing to be able to use `tristate_optionals` with mutations having lists in their parameters?

Thank you for your help and don't hesitate if you need more details!
knaeckeKami commented 6 months ago

Thanks!

Most likely related to https://github.com/gql-dart/gql/issues/436 and https://github.com/google/built_value.dart/issues/124

KevinDespoulainsTR commented 6 months ago

Ok, I see, thank you for the links!

Do you have a workaround for it? (Excluding adding addBuilderFactory to the serializers.gql.g.dart file because if someone else runs the build_runner command it will erase it)

knaeckeKami commented 6 months ago

unfortunately, no workaround at this time.

(other than forking gql_code_builder and adding the builder factories here https://github.com/gql-dart/gql/blob/master/codegen/gql_code_builder/lib/serializer.dart#L54 )

knaeckeKami commented 6 months ago

Actually, I think a workaround would be to add a Workaround type to the graphql schema which has the list in the non-nullable form.

type Workaround {
  field: [PokemonUpdateInput!]!
}

This would add the builder factory.

KevinDespoulainsTR commented 6 months ago

Actually, I think a workaround would be to add a Workaround type to the graphql schema which has the list in the non-nullable form.

type Workaround {
  field: [PokemonUpdateInput!]!
}

This would add the builder factory.

This is a nice idea, thank you for your help!