graphql / graphiql

GraphiQL & the GraphQL LSP Reference Ecosystem for building browser & IDE tools.
MIT License
15.97k stars 1.71k forks source link

Multi-project config file not working for schema introspection #2293

Open soumi-akira opened 3 years ago

soumi-akira commented 3 years ago

I want to use multiple GraphQL endpoint on single project, but this extension seems load only one (first) project even if multiple project exists on graphql.config.yml.

Here's example, only 3 files on directory. Open the directory with VSCode that installed this extension.

graphql.config.yml

projects:
  rickandmortyapi:
    schema: https://rickandmortyapi.com/graphql
  spaceX:
    schema: https://api.spacex.land/graphql/

spacex.graphql

query getUsers {
  users {
    id
    name
  }
}

query getDragons {
  dragons {
    id
    name
  }
}

rickandmorty.graphql

query getCaracters {
  characters {
    results {
      name
    }
  }
}

query getLocations {
  locations {
    results {
      name
    }
  }
}

In above case, rickandmorty.graphql is perfectly validated and auto completed but spacex.graphql throws validation error.

Cannot query field "users" on type "Query"

Yes, I know it is difficult to find proper project for each .graphql file automatically. So is there any way to assign specific project to each .graphql file? Can I find some reference about this anywhere?

If there's no way so far, I want feature like this.

spacex.graphql

#[[spaceX]]
query getUsers {
  users {
    id
    name
  }
}

query getDragons {
  dragons {
    id
    name
  }
}

rickandmorty.graphql

#[[rickandmortyapi]]
query getCaracters {
  characters {
    results {
      name
    }
  }
}

query getLocations {
  locations {
    results {
      name
    }
  }
}
soumi-akira commented 3 years ago

Auto detection by annotation inside file is best but even it is good to select project manually by using command pallet I think.

like ctrl or cmd + P -> >VSCode Graphql - Change Project

patryk-smc commented 2 years ago

I have same issue, have you found any workaround @soumi-akira ?

soumi-akira commented 2 years ago

@patryk-smc The only workaround I found is activating one project by commenting out others😑

ferm10n commented 2 years ago

I thought that setting documents inside the project config would help it determine the project to use for each file. Something like this:

projects:
  rickandmortyapi:
    schema: https://rickandmortyapi.com/graphql
    documents:
      - rickandmorty.graphql
  spaceX:
    schema: https://api.spacex.land/graphql/
    documents:
      - spacex.graphql

However, inspecting the GraphQL Language Server output panel shows that it seems to just pick the first project defined every time ("projectName":"rickandmortyapi")

ferm10n commented 2 years ago

Ah, looks like the issue I mentioned is related to https://github.com/graphql/graphiql/pull/1715 idk if you guys were on windows or not, but I was. Looks like there's an open issue here for bumping the dependency too https://github.com/graphql/vscode-graphql/issues/320

patryk-smc commented 2 years ago

I'm on mac...

acao commented 2 years ago

I don’t think this will solve the multi-project config issue. This known issue is on our roadmap, it will take us a while since we‘re all volunteers

Chnapy commented 2 years ago

@acao maybe I can help working on this issue since it would help my job team.

If i'm right project is selected using document URI via GraphQLCache#getProjectForFile, using graphql-config documents if defined.

Because we can have in a single file multiple gql template literals on different projects, we should select project based on the template literal content only.

From what I know, there is no "official" or common ways to define project used by an operation. For example, in my team we configured Apollo to select project using operation name.

query CatalogProduct { ... }  # target "Catalog" project

But others may prefer using a tag.

# project: Catalog
query Product { ... }

To handle these cases and avoid being too opinionated I suggest using Regex extracting project name from template literal. I imagine a property like projectNameRegex placed into graphql-config file. And if this property is not defined, then stay on the current logic.

Hard part would be passing current code logic from document to template literal. Uses of GraphQLCache#getProjectForFile would be replaced by something like GraphQLCache#getProjectForTemplate.

Afaik this solution would not impact #2379

I would be happy to start working on a PR, but first let's agree on where to go :+1:

acao commented 2 years ago

@Chnapy this would require changes to graphql-config, would you like to propose this change there first? getProjectForFile is an abstraction around graphql config.getProjectForFile().

The graphql config projects configuration convention is decided upon by graphql config, not this library

Chnapy commented 2 years ago

@acao I don't see why it would be required. My suggestion does not use config.getProjectForFile(), since it's not based on filepath. I suggested a getProjectForTemplate() function which would use a regex extracting project name from template literal.

I would use graphql-config only to store this regex, using extensions. Nothing to change in this library afaik :+1:

acao commented 2 years ago

@Chnapy so users would need to annotate every single template literal for it to work? or change the name of every query. I don't think this approach is sustainable, though I'm glad it worked for your team. We cannot implement strict conventions like these, as this extension is used by people using all kinds of projects, frameworks and conventions. We're a reference implementation, besides, so it's not up to us to set any conventions outside of the spec.

We will remain with using graphql config to define project configurations, we just need to fix the multi-project cache and make it work with workspaces. Hopefully someone has time to pick it up, work has been busy so it may be some more months until I can get to this, but I think about it all the time don't worry haha

If folks want a multi-project LSP server and vscode extension that works now, and you're using relay, try the relay extension! it's really incredibly and it works with multi projects (called environments in relay) and multi-workspaces.

acao commented 1 year ago

If someone would like to help jump start this effort, please provide a PR with a failing test case so we can start tracking down how to fix it

let's make sure the test works with this relatively nascent graphql-config format as well:

schema:
  - http://localhost:4000/graphql:
      headers:
        Authorization: Token
  - http://localhost:4001/graphql:
      headers:
        Authorization: Token