Graphql-code-generator: plugin development documentation?

Created on 24 Mar 2020  路  10Comments  路  Source: dotansimha/graphql-code-generator

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

I'm trying to author a new plugin (python-operations) in my fork of this repo. However, while the docs talk about the basics of plugin development, I'm hung up on tooling issues that even before that. A selection of things:

  • How do I install the repo properly? I used some combination of yarn/lerna to get it into a valid state, and then I did _something_, and now my builds are failing and VS Code is complaining, unable to resolve @graphql-codegen/* dependencies.
  • What's a good development workflow for testing a new plugin on a real codebase? I matched versions with my project and tried to symlink in my new plugin, but it complained about having multiple versions of (I think) graphql (an error message which I greatly appreciate, but means I have some hacky workaround to test my very-much-still-in-development plugin on my project).
  • Are there common unit or integration tests that cover every GraphQL language feature that plugins should attempt to support? For instance, I don't use subscriptions and am not familiar with them, but if there were even one big integration test fixture that covers the syntax and I could compare what e.g. the typescript plugin does for it, I'm reasonably confident I could make a passable Python equivalent.
  • I'd like to reuse the BaseDocumentsVisitor to do python-operations, but there are a _lot_ of moving parts. I'm trying to learn how SelectionSetToObject and BaseSelectionSetProcessor and OperationVariablesToObject and DeclarationBlock work simultaneously and it's pretty confusing. A document that explains what their role is and how they interact with each other would be awesome, because I think there's a lot in there I can reuse, but they also appear somewhat coupled to Flow/Typescript.

Describe the solution you'd like

More documentation! What's on the site now is a good start, but only covers the very basics and assumes you're working in your own repo, which I'm not (partly because I'm targeting Python, so I don't want to have to set up a node package when I already have graphql-code-generator available, and partly because I'm interested in eventually contributing this back to the mainline).

Describe alternatives you've considered

Trying random stuff only works for so long. I really can't figure out how I got my repo into this state, and why the nuclear option of deleting all node_modules and starting over isn't working.

Additional context

Similar to https://github.com/dotansimha/graphql-code-generator/issues/951, but that one is quite old and appears to have been the impetus for writing the documentation that currently exists.

docs enhancement waiting-for-release

Most helpful comment

Done in: https://github.com/dotansimha/graphql-code-generator/pull/3895 (https://github.com/dotansimha/graphql-code-generator/blob/fixes/website/docs/custom-codegen/contributing.md), this will be available in the website soon.

All 10 comments

I actually asked the same question in the Discord 15 minutes ago, hopefully get some good info.

Thank you, I'm working on improving it now :)

Done in: https://github.com/dotansimha/graphql-code-generator/pull/3895 (https://github.com/dotansimha/graphql-code-generator/blob/fixes/website/docs/custom-codegen/contributing.md), this will be available in the website soon.

Done in 1.13.3

Thank you! I'll pick my Python work back up and take a look.

@seansfkelley Hey, are you still working on this? I was thinking about making the same sort of package you were, but it seems redundant and I wouldn't want to step on your toes if this is still under development. Or, if you want someone to help with it, I'd be more than happy to.

@Andrew-Talley unfortunately I haven't had enough time to give this the attention it needs. I would _really really_ love to have this, but I've had to just work around the few cases I'd use it for with manually-defined types. Boo.

If you want to pick it up, that would be fantastic. I'd be happy to take a look over whatever you put together, if that helps. That said, you can find my changes at https://github.com/seansfkelley/graphql-code-generator/tree/python-support but be warned they're a hodgepodge of half-baked ideas and me trying to understand the types of things I'm asking about in this issue.

I did end up generating some promising types. The basic design I was going for was:

  • Uses Pydantic. Love this library.
  • The "global" type generator would only output scalars, enumerations and input types.
  • The "operations" type generator would define purpose-built types according to the operation in question (this is different than the Typescript generator, which generates all types in the global space, and then uses Pick/Partial/whatever to select subsets of them for operations).

This made code that, when used with the near-operations-file preset, looked like (from memory here -- sorry if this doesn't match with what it does exactly):

# Assuming a sibling file defines some query:
# query getStuff(input: MyInputType) {
#   fooBar { # of type FooBar!
#     baz # of type String
#   }
# }

from wherever.you.set.global.types.to import BaseModel

class GetStuff(BaseModel):
  class FooBar(BaseModel):
    baz: Optional[str]

  foo_bar: FooBar

A couple things to notice about this that I liked:

  • Though the selection set for any given type (e.g. FooBar) may vary in different queries, it always takes the same name when generated. This is because you get a nice behavior where the enclosing class acts as a namespace (like GetStuff.FooBar) which makes it abundantly clear both what type the selection set is on and that this class definition is only for this operation.
  • Pydantic has "alias generators" that make it super easy to translate between camelCase GraphQL and snake_case Python so it's idiomatic in all usages. (That's what the BaseModel import is doing here, along with a couple of other behaviors like disallowing extraneous fields and disallowing mutations.)

Hope that's helpful, and really look forward to any progress you make on this! Maybe the new C# generator can be a helpful guide for non-Javascript-family languages.

@seansfkelley Thank you for all of that, that'll be super helpful. I'm really hoping I'll be able to turn this into something close to as high-quality as the rest of the languages. And thank you for the offer to look it over, I may take you up on it.

@seansfkelley this is awesome! do you wish to create a WIP PR for that? this way we can help you wish developing this new plugin :)

Sure, if you think that would be helpful! I opened https://github.com/dotansimha/graphql-code-generator/pull/4144, but as noted here and there, I won't have time to contribute it beyond reviewing/testing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mszczepanczyk picture mszczepanczyk  路  3Comments

SimenB picture SimenB  路  3Comments

zenVentzi picture zenVentzi  路  3Comments

iamdanthedev picture iamdanthedev  路  3Comments

leebenson picture leebenson  路  3Comments