JetBrains / js-graphql-intellij-plugin

GraphQL language support for WebStorm, IntelliJ IDEA and other IDEs based on the IntelliJ Platform.
https://jimkyndemeyer.github.io/js-graphql-intellij-plugin/
MIT License
879 stars 97 forks source link

[v2] Merged schemas conflict. Query type tried to redefine existing Query type. #201

Closed ph55 closed 5 years ago

ph55 commented 5 years ago

Updated to latest version for string literals. But now getting error for Query override.

I'm using different schemas files that then being merged by grpahql-tools .

Version and Environment Details

Operation system: macOS 10.14.2 IDE name and version: PhpStorm 2018.1.7 Plugin version: 2.0.0-alpha-3

Expected Behaviour

Shouldn't throw error

Actual Behaviour

user.gql image

image

Probably conflicting config.gql:

scalar JSON

type Query {
  config(name: String): JSON
}

Doesn't work neither with .graphqlconfig:

{
  "includes": [ "*.gql" ]
}

Nor with scope: image

jimkyndemeyer commented 5 years ago

Hi Alex.

Thanks for trying out the alpha.

The plugin appears to have discovered a definition of the Query type in more than one location. Please review the docs linked from https://github.com/jimkyndemeyer/js-graphql-intellij-plugin/releases/tag/2.0.0-alpha-3 about how schema discovery works. Note for example, that some npm packages include graphql definitions that may cause conflicts if they are unintentionally included in schema discovery.

If you still encounter an issue, please link/attach a small project that reproduces the issue.

Best regards, Jim.

ph55 commented 5 years ago

The plugin appears to have discovered a definition of the Query type in more than one location.

Exactly.

But this shouldn't be the issue. Because there is such thing as schema stitching. You could have many Query types in separate files that merged. https://www.apollographql.com/docs/graphql-tools/schema-stitching.html

Here the repo: https://github.com/ph55/js-graphql-intellij-plugin-201

jimkyndemeyer commented 5 years ago

Hi Alex.

Ah, I didn't catch that schema stitching was involved.

For this use case the plugin can't automatically discover what your effective schema is using GraphQL files containing SDL since schema stitching can rename types, move fields etc.

What you'll need to do is to use introspection to let the plugin discover your fully stitched schema, and ensure that your config only includes the files where you will be consuming the stitched schema, e.g. in your components.

So, depending on your project structure you may need .graphqlconfig files for:

You should be able to make this work. See https://github.com/prisma/graphql-config#specifying-includesexcludes-files

Once you've configured "A+B" with the URL for your stitched endpoint, you can click the green arrow in the editor gutter in the config editor, and it will write the introspection result to the file specified in "schemaPath". Then make sure that you use "include"/"exclude" so "A" and "B" are not discovered where you'll be using the stitched schema.

Hope that helps.

Best regards, Jim.

ph55 commented 5 years ago

Thanks for help. Really appreciate it.

I've implemented the flow you described - https://github.com/jimkyndemeyer/js-graphql-intellij-plugin/issues/201#issuecomment-451404723

Seems like 'Query' error is gone but there is another error now. User type can't recognise Country imported from another folder.

User

.graphqlconfig

{
  "includes": ["../country/*.graphql", "*.graphql"]
}

user.graphql

type Query {
  user(id: ID!): User
  users: [User]
}

type User {
  id: ID!
  email: String!
  username: String!
  firstName: String
  lastName: String
  phone: String
  country: Country!
}

Country

.graphqlconfig

{
"includes": ["*.graphql"]
}

country.graphql

type Country {
  id: ID!
  name: String!
  iso2: String!
  iso3: String!
  isoNum: Int!
  phoneCode: Int!
  isBlocked: Int!
}

image

Repo is the same: https://github.com/ph55/js-graphql-intellij-plugin-201

ph55 commented 5 years ago

Found solution. It works with single .graphqlconfig file with devision to projects inside:

{
  "projects": {
    "config": {
      "includes": ["./config/*.graphql"]
    },
    "user": {
      "includes": ["./country/*.graphql", "./user/*.graphql"]
    }
  }
}
ph55 commented 5 years ago

Ok. Another issue popped up.

If any of components depends on the type of another component - Query error will be thrown as well.

Example: Trader depends on User type. Both Trader and User have type Query and type Mutation definitions.

.graphqlconfig

{
"projects": {
"user": {
"includes": ["./country/*.graphql", "./user/*.graphql"]
},
"trader": {
"includes": ["./user/*.graphql", "./trader/*.graphql"]
}
}
}

User.graphql


type Query {
user(id: ID!): User
users: [User]
}

type Mutation { register(input: RegisterInput!): User }

input RegisterInput { email: String! password: String! }

type User { id: ID! email: String! username: String! firstName: String lastName: String phone: String country: Country! }


> Trader.graphql
```gql
type Query {
  trader(id: ID!): Trader
  traders: [Trader]
}

type Mutation {
  register(input: TraderRegisterInput!): Trader
}

type Trader {
  id: ID!
  user: User!
}

input TraderRegisterInput {
  email: String!
  password: String!
  currency: String!
}

Errors: image

image

Repo is the same: https://github.com/ph55/js-graphql-intellij-plugin-201


Maybe we could think about more simple and more maintainable way to handle merged schemas. I think it will be relevant for large scale applications.

Maybe some flag in settings that will not check Query and Mutation redefine.

ph55 commented 5 years ago

Ok. So I found the proper way to handle this. Via extend !

.graphqlconfig

{
"schemaPath": "./root.graphql",
"projects": {
"app": {
"includes": [
"./config/*.graphql",
"./country/*.graphql",
"./user/*.graphql",
"./trader/*.graphql"
]
}
}
}

root.graphql


scalar JSON

type Query type Mutation


> trader.graphql
```gql
extend type Query {
  trader(id: ID!): Trader
  traders: [Trader]
}

extend type Mutation {
  registerTrader(input: TraderRegisterInput!): Trader
}

type Trader {
  id: ID!
  user: User!
}

input TraderRegisterInput {
  email: String!
  password: String!
  currency: String!
}

Repo is the same: https://github.com/ph55/js-graphql-intellij-plugin-201

ktersius commented 5 years ago

@ph55 If I may ask how did you combine your graphql files into one schema?

I'm currently using https://github.com/prisma/graphql-import but they don't seem to support extend. https://github.com/prisma/graphql-import/issues/42

So I can get the plugin happy with your suggestion but then graphql-import stops working as they just skip over all types that have extend.

ph55 commented 5 years ago

@ktersius Sure. I'm using NestJS framework which handles schema stitching. I think it's supported by default in Apollo graphql server. You can check it's module here: https://github.com/nestjs/graphql

ktersius commented 5 years ago

@ph55 Thanks. I ended up using https://github.com/Urigo/merge-graphql-schemas which seems to do the job.

ghost commented 2 years ago

i don't think this is feasible for me as it's just too much config work