0no-co / GraphQLSP

TypeScript LSP plugin that finds GraphQL documents in your code and provides diagnostics, auto-complete and hover-information.
https://gql-tada.0no.co
MIT License
330 stars 13 forks source link

Support reading multiple schema files (glob pattern) #264

Open davidesigner opened 3 months ago

davidesigner commented 3 months ago

Hey there,

As GQL support multiple schema files, I would like to know if you plan to support this kind of parsing method:

{
  "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schema": "./app/schema/**/*.graphql",
        "tadaOutputLocation": "./app/types/graphql-env.ts"
      }
    ]
}

For know, I need to create a script that generates a single common schema file to make GraphqlSP working.

This is not a good developer experience because:

Let me know if it's unclear or if you know a workaround? Thanks for you help!

levrik commented 3 months ago

Sadly this is also a blocker for me so I have to continue using classic code generation tools.

kitten commented 2 months ago

At least when using GraphQLSP with gql.tada, this will be resolved, RFC: https://github.com/0no-co/gql.tada/issues/248

Implementation PRs to land soon are:

Closing this in favour of https://github.com/0no-co/gql.tada/issues/248, since that tracks this. For non-gql.tada usage this will likely not be possible since we have no type hints / usage-patterns to go off of.

davidesigner commented 2 months ago

If I understand what you prepare, with this schema configuration that split schema by domains:

Screenshot 2024-04-26 at 09 29 54

We will need to do something like that:

{
  "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schemas": [
          {
            "name": "queries",
            "schema": "./app/schema/queries.graphql",
            "tadaOutputLocation": "./app/types/gql/queries-introspection.d.ts"
          },
          {
            "name": "accommodation",
            "schema": "./app/schema/queries/accommodation.graphql",
            "tadaOutputLocation": "./app/types/gql/accommodation-introspection.d.ts"
          },
          {
            "name": "alert",
            "schema": "./app/schema/queries/alert.graphql",
            "tadaOutputLocation": "./app/types/gql/alert-introspection.d.ts"
          },
          {
            "name": "block-content",
            "schema": "./app/schema/queries/block-content.graphql",
            "tadaOutputLocation": "./app/types/gql/block-content-introspection.d.ts"
          },
          // etc. (maybe more than 20th time)...
        ]
      }
    ]
}

Rather than we can do with Codegen that supports glob pattern:

{
  "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schema": "./app/schema/**/*.graphql",
        "tadaOutputLocation": "./app/types/graphql-env.ts"
      }
    ]
}

Have I understood correctly? Thanks 🙏

JoviDeCroock commented 2 months ago

The multi-schema is not to merge schema's no, we have no glob support for now and atm I would encourage you if the endpoint has a merged schema to merge schemas or introspect the endpoint

levrik commented 2 months ago

@JoviDeCroock I got really excited when I heard about multiple schema files being supported now. Then I saw that it doesn't support merged schema. We're pulling in our backend which contains the schema definitions simply as a submodule to our frontend codebase and then read the schema from there. The point of gql.tada would be to avoid some extra build steps like code generation but now require me to execute some script to prepare the schema files which kind of defeats the purpose of this IMO. I'll simply stay with code generation tools as I'm not seeing any advantage here.

JoviDeCroock commented 2 months ago

@levrik this is still an open-source repository, you are free to create RFC's and even contribute them. We have limited time and prioritise according to our own balance.

I will re-open this issue as it's not solved but we might benefit from having a clearer description, which has been done by iterating

davidesigner commented 2 months ago

Yep my bad, sorry @JoviDeCroock if it was not clear, thanks again for your nice package and for reopening the issue!

levrik commented 2 months ago

@JoviDeCroock Sadly I won't have the time to contribute. If I sounded a bit too harsh I'm sorry for that. I just wanted to point out this use-case. I think such a setup might be not too uncommon and I only wanted to point out that by not supporting it you basically make your project unusable to many people. I'm fine with relying on alternatives.

kitten commented 2 months ago

This is a bit besides the point, but let me take a larger circle into why we haven't added support for this yet.

Creating multiple *.graphql files to compose into a schema for an API to consume is a bit of an old and imho inferior pattern for GraphQL API creation. There are many better code-first solutions now, but even without them, co-located patterns with graphql-tags on the server-side exist.

The key here to understand is that these *.graphql files, while composing into a schema, are technically server-side artifacts, and we see them as different than a single introspection JSON file or single SDL schema.graphql file.

For example, if you're using *.graphql SDL files as split input files to your server, you're probably using GraphQL Code Generator (or a similar tool) to generate resolver types and to embed them in your server. In that case you already have a code generator that can output a schema.graphql file.

Say, for instance, you're using this: https://the-guild.dev/graphql/codegen/docs/guides/graphql-server-apollo-yoga-with-server-preset No matter what else your GraphQL Code Generator is doing, you can always also use it to also output a merged SDL file: https://the-guild.dev/graphql/codegen/plugins/other/schema-ast

A lot of servers again also support writing a merged SDL file to disk in development to merge separate parts of the schema into one file. An alternative to this is also URL-introspection, which can either be done on every gql.tada command or in GraphQLSP, or by running gql.tada generate output. The merged file logic is pretty simple though and can also be written by hand.

If we were to support **/*.graphql merging in these tools, then the next natural question would be to also load **/*.ts (which is problematic, but as it has some caveats, but can be done), but that then poses the question of what happens when the server isn't written in TS/JS.

Basically, there's a neverending list of creating GraphQL APIs and servers. A merged SDL/JSON schema file however is what we see as the best cross-over point for intercompatibility.

In theory, code-first tools can achieve deeper integration than this, and we do have an issue related to this: https://github.com/0no-co/gql.tada/issues/10 But server-authoring is simply a domain that's outside of GraphQLSP and gql.tada and — so far — we've been quite strict about this separation

levrik commented 2 months ago

@kitten The backend is written in Python and uses https://github.com/mirumee/ariadne. It directly consumes the schema spread over several files. While maybe the code-first generation approach is very popular in JS/TS it doesn't seem to be that much outside.