type-graphql icon indicating copy to clipboard operation
type-graphql copied to clipboard

Feature Request: Library to Generate Client

Open ozyman42 opened this issue 4 years ago • 3 comments

Is your feature request related to a problem? Please describe. Trying to write client code which queries a graphql server whose resolvers and types were defined using type-graphql.

I'm building a webpack-dev-server alternative that supports HMR in node and web and I'd like to use graphql to define a data-transfer method agnostic API for fetching bundle updates & eventually support remote javascript debugging

Describe the solution you'd like I would like a typescript graphql client to be generated at compile-time based on the type-graphql @ObjectType definitions, with a design-time, typed client API available. This could be a separate package from type-graphql, like type-graphql-client.

Describe alternatives you've considered

  • https://github.com/helios1138/graphql-typed-client
  • https://github.com/mobxjs/mst-gql
  • https://github.com/samdenty/gqless

The third option doesn't work because it's React specific. The first two are headed in the right direction, but they vend a CLI that requires connection to a running graphql server. These options just inspect the predefined schema in order to generate the client, so theoretically we should be able to generate a client based on type-graphql @ObjectTypes, since these @ObjectTypes act as the source of truth for generating a graphql schema.

Additional context Ideally, the type-graphql annotated @ObjectType classes would be isomorphic typescript, a DTO shared between client and server. Often times clients are bundled (via webpack for example), but right now there are difficulties bundling type-graphql into a webpack bundle because it has node-specific dependencies (there are imports to fs and path in the codebase for example) which means I can't bring an @ObjectType annotated class into a web targeted bundle without some config hacks. One workaround would be to separate the type-graphql annotations into a separate library like type-graphql-annotations which has zero dependencies and is written to run in any javascript runtime; in this case the annotations would be used more like meta-data tags rather than performing any operations, and then the main type-graphql node library or the type-graphql-client library would be able to interpret the meaning of the tags then generate a graphql schema via graphql-js or a graphql client respectively.

Ideally the type-graphql-client library would only know how to generate query strings, and would have no knowledge of where or how to submit the strings. That choice would be left up to clients of the library.

If you're open to something like this, I'd be happy organize this project (understand type-graphql more, organize a backlog, work on some epics/stories/tasks).

ozyman42 avatar Nov 08 '19 05:11 ozyman42

Have you looked at https://github.com/mobxjs/mst-gql? I've been using it for a similar use-case.

fullofcaffeine avatar Nov 08 '19 07:11 fullofcaffeine

@fullofcaffeine thanks for the recommendation. MST-GQL seems to have the same issue as the other examples I mentioned: they require a running graphql server from which to generate a typescript client. I do like MST though so I'll probably give that library a try until a solution like the one I'm proposing becomes available.

ozyman42 avatar Nov 08 '19 17:11 ozyman42

The first two are headed in the right direction, but they vend a CLI that requires connection to a running graphql server.

Incorrect. Most of IDE plugins or other code generators can use the GraphQL schema file, not only the running server to make an introspection query:

-s, --schema <./*.graphql>                   glob pattern to match GraphQL schema definition files

I would like a typescript graphql client to be generated at compile-time based on the type-graphql @ObjectType definitions

It's not possible to do that in compile-time without 3rd-party TS compiler plugin. How would you distinguish in type system if the resolver class method is query or mutation?

My statement is that the querying part of the GraphQL schema is very well designed (apart from arguments for fragments) and there's no need for a client lib to describe and generate that queries. For all my apps - React, Angular, Node - I just use emitSchemaFile option (or a custom script that just build the schema without bootstraping the connection or server) to write the schema SDL to file and then both VSCode plugin autocomplete my queries in IDE and GraphQL Code Generator generates the TS types for my queries or even React hooks or Angular services to perform the operation on the server.

There are also other tools like https://github.com/acro5piano/typed-graphqlify that allows you to write typesafe queries without connecting to the schema but because of that you will have false positive when the schema change and your queries will fail and runtime. GraphQL Code Generator doesn't have this problem as it always validates all your queries against the schema. Also, if you prefer more object-oriented way to describe your queries, you can use graphql-bindings for that.

So to sum up - there's no way for now to create a client that checks the queries GraphQL API in compile-time without a build-step like run buildSchema to make emitSchemaFile works. You have to use other, standard GraphQL ecosystem tools for that.

MichalLytek avatar Nov 10 '19 10:11 MichalLytek