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

[Idea] Opinionated (graphql) transformer #34

Open
emmenko opened this issue Nov 2, 2020 · 3 comments
Open

[Idea] Opinionated (graphql) transformer #34

emmenko opened this issue Nov 2, 2020 · 3 comments
Labels
enhancement New feature or request

Comments

@emmenko
Copy link
Member

emmenko commented Nov 2, 2020

Is your feature request related to a problem? Please describe.

At the moment 98% of our graphql transformers use the addFields to set the __typename.

Describe the solution you'd like

Maybe we should provide a preconfigured graphql transformer that always sets the __typename.

For example:

Transformer.graphql('Author')

Transformer.graphql('Author', {
  buildFields: ['books'],
})

Describe alternatives you've considered

Instead of Transformer.graphql, we can have a GraphqlTransformer.

@emmenko emmenko added the enhancement New feature or request label Nov 2, 2020
@emmenko
Copy link
Member Author

emmenko commented Nov 2, 2020

@pa3 @tdeekens any thoughts about this?

@tdeekens
Copy link
Contributor

tdeekens commented Nov 2, 2020

I like the idea but I also like that all transformers have the same API no matter their type 🤔.

One thing, unrelated to this, is that I wonder if we should "auto-build" nested fields if possible. That removes already quite a bit of cruft.

@ahmehri
Copy link
Member

ahmehri commented Jun 10, 2022

I encountered a use case where having __typename in the generated data is not convenient. It's when generating data related to GraphQL Input Types, such as AttributeGroupDraft which is used as an argument to the createAttributeGroup mutation. Because __typename is not allowed on Input Types, the related mutation will fail. To solve this, __typenames can be stripped from the generated data by transformers.

// Generator
const generator = Generator({
  fields: {
    name: fake(() => LocalizedString.random()),
    description: fake((f) =>
      f.random.arrayElement([null, LocalizedString.random()])
    ),
  },
});

// Transformers
function omitTypename(object) {
  return omitDeep(object, '__typename');
}
const transformers = {
  graphql: Transformer('graphql', {
    replaceFields({ fields }) {
      return {
        ...fields,
        name: buildField(fields.name, 'graphql').map(omitTypename),
        description:
          fields.description &&
          buildField(fields.description, 'graphql').map(omitTypename),
      };
    },
  }),
};

// Usage
const attributeGroupDraft = AttributeGroupDraft.random().buildGraphql();

However, this is not ideal as doing this will become redundant (needs to be done for each generated GraphQL data). One way to solve this is to get inspired by how Apollo GraphQL handles __typename, and provide a new addTypename option to the buildGraphql builder, with a default value of true. This way, the consumer can correctly generate input types by setting the option value to false.

// Generator
const generator = Generator({
  fields: {
    name: fake(() => LocalizedString.random()),
    description: fake((f) =>
      f.random.arrayElement([null, LocalizedString.random()])
    ),
  },
});

// Transformers
-function omitTypename(object) {
-  return omitDeep(object, '__typename');
-}
const transformers = {
  graphql: Transformer('graphql', {
-    replaceFields({ fields }) {
-      return {
-        ...fields,
-        name: buildField(fields.name, 'graphql').map(omitTypename),
-        description:
-          fields.description &&
-          buildField(fields.description, 'graphql').map(omitTypename),
-      };
-    },
+    buildFields: ['name', 'description'],
  }),
};

// Usage
- const attributeGroupDraft = AttributeGroupDraft.random().buildGraphql();
+ const attributeGroupDraft = AttributeGroupDraft.random().buildGraphql({ addTypename: false });

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

No branches or pull requests

3 participants