sam-goodwin / typesafe-dynamodb

TypeSafe type definitions for the AWS DynamoDB API
Apache License 2.0
205 stars 11 forks source link

Type-safe GraphQL client #45

Closed RaeesBhatti closed 1 year ago

RaeesBhatti commented 1 year ago

First of all, thank you for creating this project! I didn't know something like this was even possible with Typescript.

I was wondering if something like this is possible for GraphQL as well. The other GraphQL type-generation solutions (https://the-guild.dev/graphql/codegen) require that you define your queries and then run a script to generate types for them. That's a bunch of manual work for every GraphQL query you're writing or changing. If something like Typesafe-DynamoDB existed for GraphQL as well, it would make life so much easier. I imagine it would work by taking the types of GraphQL schema and providing a function that can make type-safe requests. Something like

const gql = new GraphQlTypeSafeClient<GraphQlSchemaTypes>({endpoint: 'https://example.com/gql'});
const response = await gql.request(`query ($name: String!) {
  pokemon(name: $name) {
    name
    type
    age
    canFly
  }
}`, { name: "Pikachu" })

In this scenario, Typescript would complain if the type of any of the variables is incorrect or not provided. Similarly, it could also check if any fields are misspelled and provide a typed response.

I don't know anything about the level of effort required to build something like this, but I'd love to take your view on this. Is this something you'd be interested in building/collaborating?

sam-goodwin commented 1 year ago

Hi @RaesChatti, thanks for reaching out! I've actually played with this idea before and would be happy help you however I can. You can see my code here: https://twitter.com/samgoodwin89/status/1308315026143367175?s=20&t=mzjBKrOkcg2pZk5KxJnEMg

This is a type-only parser of GraphQL AST. Theoretically, you could use it to then traverse and generate the interface { name: "string" } for that GraphQL string.

In my testing, this technique quickly bogs down the compiler and cannot parse past a certain length string. TS's types are not really meant for lexing and parsing strings 😅.

That said, we probably don't have to parse the entire AST to achieve the result you're looking for. I assume you only care about this bit:

query ($name: String!) 

Parsing this information should be significantly lighter weight than what I did.

Question: how will you deal with non-scalar/intrinsic types, such as enums or custom input types? How will we know what their shape is? For that - we'd need to know the entire schema at the type-level. A prototype that only works with scalars/intrinsics would probably be straightforward to achieve.

github-actions[bot] commented 1 year ago

This issue is now marked as stale because it hasn't seen activity for a while. Add a comment or it will be closed soon. If you wish to exclude this issue from being marked as stale, add the "backlog" label.

github-actions[bot] commented 1 year ago

Closing this issue as it hasn't seen activity for a while. Please add a comment @mentioning a maintainer to reopen. If you wish to exclude this issue from being marked as stale, add the "backlog" label.