0no-co / gql.tada

🪄 Magical GraphQL query engine for TypeScript
https://gql-tada.0no.co
MIT License
2.56k stars 43 forks source link

RFC: Provide built-in multi-schema support ("Multiple Schemas") #248

Closed kitten closed 5 months ago

kitten commented 5 months ago

Summary

In applications today, it's not uncommon anymore to consume one (or more) GraphQL API(s) while also building one. When this is done in a monorepo and we wish to use gql.tada to both consume our own GraphQL API on the front-end and third-party APIs on the back-end, we end up with multiple schemas.

Currently, these conflict and setting them up means that:

Instead, we should be able to natively support multiple schemas.

Proposed Solution

The configuration should be extended to support multiple schemas. Currently, the config is instantiated with a single schema, which is a format we should still support after this change:

{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schema": "./schema.graphql",
        "tadaOutputLocation": "./src/graphql-env.d.ts"
      }
    ]
  }
}

The most convenient configuration would be to allow schema to accept multiple configurations:

{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schema": [
          {
            "url": "./schema.graphql",
            "tadaOutputLocation": "./src/graphql/graphql-env.d.ts"
          },
          {
            "url": "https://api.example.com/graphql",
            "tadaOutputLocation": "./src/graphql/example-graphql-env.d.ts"
          }
        ]
      }
    ]
  }
}

Selecting a schema should be automatically done in the CLI and GraphQLSP.

Requirements

There may be better options to changing schema to a schema[] array in the config. However, we need to definitely scope all tada-specific options to the schema itself, mainly:

Instead of discovering graphql calls by template, we should:

gql.tada should expose a hidden, optional property on graphql that allows us to identify the schema with a typeChecker check. Retrieveing this property happens using a StringLiteral type check, similar to this union: https://github.com/0no-co/GraphQLSP/blob/c4630f62bd435ffacb89ab2a66860b96a9b9bdee/packages/graphqlsp/src/fieldUsage.ts#L359-L367 The property could have a signature of __schema?: string;, where string is the string literal specifying the schema[].url property.

The gql.tada CLI and graphqlsp can then switch schemas by matching graphql.__schema against schema[].url in the config.

The schema loaders should be extended to automatically support multiple schemas and abstract them away as much as possible.

Open Questions

Requests

Prior discussions

Prior Discord messages

kitten commented 5 months ago

This has been released in gql.tada 1.6.0 (+ @0no-co/graphqlsp@^0.12.0). There's more information in the corresponding announcement devlog post: https://gql-tada.0no.co/devlog/2024-04-26