gatzjames / insomnia-plugin-graphql-codegen-import

Insomnia plugin that generates GraphQL operations in your workspace
MIT License
9 stars 4 forks source link

Generates large files freezing Insomnia #8

Open TuringJest opened 2 years ago

TuringJest commented 2 years ago

Nice plugin! Looks like there are some issues with recursive types however. I get many very large generated files which freeze Insomnia when opened.

gatzjames commented 2 years ago

Thanks 🙏 Do you have an example schema I could use to reproduce the behavior? Is it happening for any recursive type?

gatzjames commented 2 years ago

Got a repro by using GitHub's graphql api which takes too long making the app unresponsive

TuringJest commented 2 years ago

In the end it's more related to the complexity of graph structures. I guess we need to be able to limit the complexity of generated operations by a maximum depth/nesting setting, just like many servers do it for the queries they accept.

If the schema is very graph-like and contains many connections, all those references will just naturally create huge queries.

Try those harmless looking schemas... 😄

type type1 {
  id: String

  type1: type1
  type2: type2
  type3: type3
  type4: type4
  type5: type5
}

type type2 {
  id: String

  type1: type1
  type2: type2
  type3: type3
  type4: type4
  type5: type5
}

type type3 {
  id: String

  type1: type1
  type2: type2
  type3: type3
  type4: type4
  type5: type5
}

type type4 {
  id: String

  type1: type1
  type2: type2
  type3: type3
  type4: type4
  type5: type5
}

type type5 {
  id: String

  type1: type1
  type2: type2
  type3: type3
  type4: type4
  type5: type5
}

type Query {
  type1: type1
}

This combined with interfaces will especially blow up queries. Every implementation of the interface will be spread.

type type1 implements someInterface {
  id: String

  type1: type1
  type2: type2
  type3: type3
  type4: type4
  type5: type5
}

type type2 implements someInterface {
  id: String

  type1: type1
  type2: type2
  type3: type3
  type4: type4
  type5: type5
}

type type3 implements someInterface {
  id: String
  field(input: String): someInterface
}

type type4 implements someInterface {
  id: String
  field(input: String): someInterface
}

type type5 implements someInterface {
  id: String
  field(input: String): someInterface
}

type Query {
  query1: type1
  query2: someInterface
}

interface someInterface {
  id: String
}
TuringJest commented 2 years ago

In our case we had a document interface with 6 different document implementations. But the document kept popping up everywhere... in client, order, position, user, etc. combined with some references between those types this completely blew up the generated queries.

gatzjames commented 2 years ago

I saw that unions generate a lot of content 😅 Could you check if this is fixed in the latest version? (retype insomnia-plugin-graphql-codegen-import in Preferences > Plugins in the app install) I've removed the circular type generation and limited the depth. Also made it so that the collection gets imported in chunks so insomnia can handle the load. Not sure if there's a parser for GraphQL schemas that allows to parse in streaming mode but worth looking into for more perf in large schemas!

TuringJest commented 2 years ago

Tried 0.3.8, looks pretty good now!

However, two new issues I get:

This schema will reproduce the issue with args.

type Type1 {
  id: String
  type2: Type2
  Type2Connection(arg: String): Type2
}

type Type2 {
  id: String

  type1: Type1
  type2: Type2
  type3: Type3
  type4: Type4
  type5: Type5
}

type Type3 {
  id: String

  type1: Type1
  type2: Type2
  type3: Type3
  type4: Type4
  type5: Type5
}

type Type4 {
  id: String

  type1: Type1
  type2: Type2
  type3: Type3
  type4: Type4
  type5: Type5
}

type Type5 {
  id: String

  type1: Type1
  type2: Type2
  type3: Type3
  type4: Type4
  type5: Type5
}

type Query {
  type1: Type1
}