gql-dart / ferry

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

How to remove the `__typename` in the `toJson` of a fragment #573

Closed ValentinVignal closed 5 months ago

ValentinVignal commented 6 months ago

It is a follow-up of https://github.com/gql-dart/ferry/issues/527

I have a schema

# lib/schema.graphql

type Pokemon {
  id: ID!
  name: String!
  type: String!
}

type Query {
  pokemons: [Pokemon!]!
  pokemon(id: ID!): Pokemon
}

and created a fragment

# lib/graphql/fragment.pokemon.graphql

fragment PokemonFragment on Pokemon {
  id
  name
  type
}

The issue I have now is that the G__typename field is included as __typename in the json generated from the toJson(). Is there a way to not include __typename in some scenarios?

knaeckeKami commented 6 months ago

hm, there's the add_typenames option for code generation. But I would not recommend deactivating this globally, especially if you use inline fragments with type conditions.

ValentinVignal commented 5 months ago

Yeah, I don't think that is a good idea to deactivate it globally. In the end, I created a SerializerPlugin to remove the __typename from the json:

import 'package:built_value/serializer.dart';

/// A plugin that removes the `__typename` field from the serialized data.
class RemoveTypenamePlugin extends SerializerPlugin {
  @override
  Object? afterDeserialize(Object? object, FullType specifiedType) {
    return object;
  }

  @override
  Object? afterSerialize(Object? object, FullType specifiedType) {
    if (object is Map && object.containsKey('__typename')) {
      return Map<String, dynamic>.from(object as Map<String, dynamic>)..remove('__typename');
    } else {
      return object;
    }
  }

  @override
  Object? beforeDeserialize(Object? object, FullType specifiedType) {
    return object;
  }

  @override
  Object? beforeSerialize(Object? object, FullType specifiedType) {
    return object;
  }
}

that I can add to my serializers when needed