Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Types of property 'middlewares' are incompatible. #151

Closed
artemzakharov opened this issue Sep 17, 2018 · 18 comments
Closed

Types of property 'middlewares' are incompatible. #151

artemzakharov opened this issue Sep 17, 2018 · 18 comments

Comments

@artemzakharov
Copy link

Bug report

  • [Yes] I have checked other issues to make sure this is not a duplicate.

Describe the bug

When using the most current versions of the graphql-yoga and graphl-shield libraries, trying to add shield({ ... }) to the middlewares option of the server creates this error:

image

(it keeps going for quite a while, just didn't want to copy and paste five dozen lines)

To Reproduce

Copy and paste the Graphql Yoga example file. No changes are necessary for the error to pop up.

Additional context

graphql-yoga version: 1.16.2
graphql-shield version: 3.2.2

@JazminElkan-Gonzalez
Copy link

JazminElkan-Gonzalez commented Sep 18, 2018

same issue, looks like "shield" type has changed from IMiddleware to IMiddlewareGenerator.
specifically it went from (in 2.2.7)

export declare function shield(ruleTree?: IRules, _options?: IOptions): IMiddleware;

to (in 3.2.2)

export declare function shield<TSource = any, TContext = any, TArgs = any>(ruleTree: IRules, options?: IOptionsConstructor): IMiddlewareGenerator<TSource, TContext, TArgs>;

@maticzav
Copy link
Owner

Hey @artemzakharov @JazminGonzalez-Rivero 👋,

I tried to reproduce the error but had no luck. I used typescript-advanced boilerplate and then installed graphql-shield as a dependency. Here are my commands;

graphql create sample
cd sample
yarn add graphql-shield

and code;

import {GraphQLServer} from 'graphql-yoga'
import {shield, allow} from 'graphql-shield'
import {Prisma} from './generated/prisma'
import resolvers from './resolvers'

const server = new GraphQLServer({
  typeDefs: './src/schema.graphql',
  resolvers,
  middlewares: [
    shield({
      Query: allow,
    }),
  ],
  context: req => ({
    ...req,
    db: new Prisma({
      endpoint: process.env.PRISMA_ENDPOINT, // the endpoint of the Prisma API (value set in `.env`)
      debug: true, // log all GraphQL queries & mutations sent to the Prisma API
      // secret: process.env.PRISMA_SECRET, // only needed if specified in `database/prisma.yml` (value set in `.env`)
    }),
  }),
})
server.start(() => console.log(`Server is running on http://localhost:4000`))

Super barebones. Since I wasn't able to reproduce the bug, I suggest you try removing node_moudles and reinstall everything. Did you by chance add graphql-middleware as a project dependency? I know this has caused compatibility errors as graphql-yoga already ships with graphql-middleware.

Let me add a quick note about the versioning; I assume you are both familiar with semantic-versioning; majors indicate backward incompatibility (X.x.x), minors indicate new features (x.X.x) and fixes are just fixes (x.x.X). So, the latest version of graphql-shield shipped with incompatible backward types - IMiddleware was changed to IMiddlewareGenerator, that's why there's also a major version bump to indicate this particular change.

I hope this clears things out a bit. Let me know if you're still experiencing the problem. 🙂

@JazminElkan-Gonzalez
Copy link

JazminElkan-Gonzalez commented Sep 19, 2018

@maticzav yeah sorry was trying to explain the change....

but continuing forward, I have a setup that passes the IMiddlewareGenerator directly to applyMiddleware() and am now encountering this error Error: Type generator exists in middleware but is missing in Schema. it seems to me as though the code in graphql-middleware is not running/generating the generator properly.... is there a specific graphql-middleware version I should be using along with this?

@artemzakharov
Copy link
Author

@maticzav I did have graphql-middleware installed, but removing it didn't seem to help. Are you aware of any other libraries that might cause a conflict?

On a side note, do you happen to have a guide for using shield with Apollo Server 2? I've been considering switching over from Yoga, but I haven't found any means to implement your library with them yet.

@jonathanheilmann
Copy link

@maticzav yeah sorry was trying to explain the change....

but continuing forward, I have a setup that passes the IMiddlewareGenerator directly to applyMiddleware() and am now encountering this error Error: Type generator exists in middleware but is missing in Schema. it seems to me as though the code in graphql-middleware is not running/generating the generator properly.... is there a specific graphql-middleware version I should be using along with this?

I'm running into the same error using graphql-middleware version 1.7.2 and have no idea on how to solve this problem.

@maticzav
Copy link
Owner

@JazminGonzalez-Rivero @artemzakharov @jonathanheilmann thanks for the feedback!

Let's first fix the problem this issue is named after. I am unable to reproduce the bug you are all facing. Since the best reproduction explanation, so far, has been to try the provided combinations of package versions, which I also tested, I am unable to conclude anything. It would be super helpful if one of you could tinker together a small repository portraying the bug. This way I can take a look into the problem and fix it if we find its nucleus in graphql-shield or graphql-middleware.


Regarding the Apollo Server issue, yes, there's a way of doing it. I don't have and don't intend to make an article or anything similar explaining the procedure as I hope we will gain middleware support in a matter of days. Nevertheless, I believe I should present the solution; you can use graphql-middleware and accompany it with makeExecutableSchema function provided by graphql-tools.

Since Apollo Server accepts schema as a parameter, you can inject it with no problem.

const schema = makeExecutableSchema({ typeDefs, resolvers })

const schemaWithMiddleware = applyMiddleware(
  schema,
  shield()
)

const server = new ApolloServer({
  mocks: false,
  schema: schemaWithMiddleware,,
});

i hope this is somewhat helpful 🙂

@morgothulhu
Copy link

Running into the same issue unfortunately. For reference I use yoga with the Lambda ctor.

@maticzav
Copy link
Owner

@morgothulhu could you pull together a reproduction repo?

@MaksimKlepikov
Copy link

MaksimKlepikov commented Oct 2, 2018

Same here. I'm just yarn upgrade --latest and now getting:

Error: Cannot find module 'graphql-middleware'
    at Function.Module._resolveFilename (module.js:547:15)
    at Function.Module._load (module.js:474:25)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/mnt/share/Git/aerobic-backend/node_modules/graphql-shield/src/shield.ts:1:1)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)

After yarn add graphql-middleware i'm getting:

Error: Type generator exists in middleware but is missing in Schema.
    at new MiddlewareError (/mnt/share/Git/aerobic-backend/node_modules/graphql-yoga/node_modules/graphql-middleware/dist/validation.js:46:23)
    at /mnt/share/Git/aerobic-backend/node_modules/graphql-yoga/node_modules/graphql-middleware/src/validation.ts:17:13
    at Array.forEach (<anonymous>)
    at Object.validateMiddleware (/mnt/share/Git/aerobic-backend/node_modules/graphql-yoga/node_modules/graphql-middleware/src/validation.ts:15:27)
    at addMiddlewareToSchema (/mnt/share/Git/aerobic-backend/node_modules/graphql-yoga/node_modules/graphql-middleware/src/middleware.ts:33:27)
    at normalisedMiddlewares.reduceRight.schema (/mnt/share/Git/aerobic-backend/node_modules/graphql-yoga/node_modules/graphql-middleware/src/middleware.ts:86:13)
    at Array.reduceRight (<anonymous>)
    at applyMiddlewareWithOptions (/mnt/share/Git/aerobic-backend/node_modules/graphql-yoga/node_modules/graphql-middleware/src/middleware.ts:78:77)
    at applyMiddleware (/mnt/share/Git/aerobic-backend/node_modules/graphql-yoga/node_modules/graphql-middleware/src/middleware.ts:129:36)
    at new GraphQLServer (/mnt/share/Git/aerobic-backend/node_modules/graphql-yoga/src/index.ts:137:13)

and

Error: Cannot use GraphQLNonNull "[Competition]!" from another module or realm.

Ensure that there is only one instance of "graphql" in the node_modules
directory. If different versions of "graphql" are the dependencies of other
relied on modules, use "resolutions" to ensure only one version is installed.

https://yarnpkg.com/en/docs/selective-version-resolutions

Duplicate "graphql" modules cannot be used at the same time since different
versions may have different capabilities and behavior. The data from one
version used in the function from another could produce confusing and
spurious results.
    at instanceOf (/mnt/share/Git/aerobic-backend/node_modules/graphql/jsutils/instanceOf.js:37:13)
    at isNonNullType (/mnt/share/Git/aerobic-backend/node_modules/graphql/type/definition.js:157:34)
    at PrismaTypescriptGenerator.TypescriptGenerator.renderFieldType (/mnt/share/Git/aerobic-backend/node_modules/graphql-binding/src/codegen/TypescriptGenerator.ts:309:9)
    at /mnt/share/Git/aerobic-backend/node_modules/graphql-binding/src/codegen/TypescriptGenerator.ts:255:48
    at Array.map (<anonymous>)
    at PrismaTypescriptGenerator.TypescriptGenerator.renderMainMethodFields (/mnt/share/Git/aerobic-backend/node_modules/graphql-binding/src/codegen/TypescriptGenerator.ts:252:8)
    at PrismaTypescriptGenerator.TypescriptGenerator.renderQueries (/mnt/share/Git/aerobic-backend/node_modules/graphql-binding/src/codegen/TypescriptGenerator.ts:190:17)
    at PrismaTypescriptGenerator.render (/mnt/share/Git/aerobic-backend/node_modules/prisma-binding/src/PrismaTypescriptGenerator.ts:13:31)
    at /mnt/share/Git/aerobic-backend/node_modules/prisma-binding/src/bin.ts:69:34
    at step (/mnt/share/Git/aerobic-backend/node_modules/prisma-binding/dist/bin.js:33:23)


Running graphql codegen ✖

index.ts

import { formatError } from 'apollo-errors';
import { GraphQLServer } from 'graphql-yoga';
import { forwardMiddleware } from './forwards';
import { Prisma } from './generated/prisma';
import { permissions } from './permissions';
import {fragmentReplacements, resolvers} from './resolvers';

import { getUser } from './utils';

const server = new GraphQLServer({
  typeDefs: './src/schema.graphql',
  resolvers,
  resolverValidationOptions: {
    requireResolversForResolveType: false,
  },
  middlewares: [forwardMiddleware, permissions],
  context: ({
    request,
    response,
    fragmentReplacements: middlewareFragmentReplacements,
  }) => ({
    request,
    response,
    user: getUser(request),
    db: new Prisma({
      fragmentReplacements: [
        ...fragmentReplacements,
        ...middlewareFragmentReplacements,
      ],
      // typeDefs: 'src/generated/prisma.graphql', // the auto-generated GraphQL schema of the Prisma API
      endpoint: process.env.PRISMA_ENDPOINT,
      secret: process.env.PRISMA_SECRET, // only needed if specified in `database/prisma.yml`
      debug: false,
      // debug: process.env.NODE_ENV !== 'production'
    }),
  }),
});

package.json

  "dependencies": {
    "apollo-errors": "^1.9.0",
    "bcryptjs": "^2.4.3",
    "graphql": "^14.0.2",
    "graphql-cli": "^2.16.3",
    "graphql-middleware": "^1.7.4",
    "graphql-middleware-forward-binding": "^1.3.2",
    "graphql-shield": "^3.2.4",
    "graphql-yoga": "^1.14.10",
    "jsonwebtoken": "^8.3.0",
    "nodemailer": "^4.6.7",
    "npm-run-all": "^4.1.3",
    "prisma": "^1.10.2",
    "prisma-binding": "^2.1.0"
  },

I discard changes in my package.json and only upgrade graphql-shield from 2.2.5 to 3.2.4 and everything is ok, my current package.json:

  "dependencies": {
    "apollo-errors": "^1.9.0",
    "bcryptjs": "^2.4.3",
    "graphql": "^0.13.2",
    "graphql-cli": "^2.16.3",
    "graphql-middleware-forward-binding": "^1.3.2",
    "graphql-shield": "^3.2.4",
    "graphql-yoga": "^1.14.10",
    "jsonwebtoken": "^8.3.0",
    "nodemailer": "^4.6.7",
    "npm-run-all": "^4.1.3",
    "prisma": "^1.10.2",
    "prisma-binding": "^2.1.0"
  },

@maticzav
Copy link
Owner

maticzav commented Oct 3, 2018

Hey @kevrat 👋,

Thank you for posting a reproduction code. You're probably experiencing the issues because your grpahql-yoga version is still on 1.14.10 which doesn't yet pack the new graphql-middleware. I advise you try updating yoga to its latest version (1.16.2) and see if the error is still present.

I hope this solves your problem 🙂

@maticzav
Copy link
Owner

maticzav commented Oct 3, 2018

OK, huge thanks to everyone for posting the reproduction code and contributing to the above discussion. I think I've finally found a pattern in the errors we have seen, here's my examination;

@artemzakharov I am sorry, but I am still unable to reproduce your bug. The steps I take are as follows;

graphql create project
yarn add graphql-shield

This results in graphql-yoga version 1.16.2 and graphql-shield version 3.2.4.

No error is shown.


Error: Type generator exists in middleware but is missing in Schema.

@JazminGonzalez-Rivero

This error occurs due to duplicated graphql-middleware package. graphql-yoga is already packed with the latest graphql-middleware version working with it. Therefore, you shouldn't install a separate one. You can resolve this by removing direct graphql-middleware dependency.


Error: Type generator exists in middleware but is missing in Schema.

@kevrat

This error occurs due to an outdated version of graphql-middleware. To fix it you should update graphql-middleware, in case you are not using Yoga; or graphql-yoga in case you do.

I'll close this issue as it seems we've covered everything hitherto discussed. If anyone finds any other bug related to this topic, don't hesitate to open another question or a reply to this thread. 🙂

@maticzav maticzav closed this as completed Oct 3, 2018
@MaksimKlepikov
Copy link

MaksimKlepikov commented Oct 3, 2018

As you say i updated graphql-yoga and now i'm getting:

Error: Cannot find module 'graphql-middleware'
    at Function.Module._resolveFilename (module.js:547:15)
    at Function.Module._load (module.js:474:25)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/mnt/share/Git/aerobic-backend/node_modules/graphql-shield/src/shield.ts:1:1)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
[nodemon] app crashed - waiting for file changes before starting...

my updated package.json

"dependencies": {
  "apollo-errors": "^1.9.0",
  "bcryptjs": "^2.4.3",
  "graphql": "^14.0.2",
  "graphql-cli": "^2.16.7",
  "graphql-middleware-forward-binding": "^1.3.2",
  "graphql-shield": "^3.2.4",
  "graphql-yoga": "^1.16.2",
  "jsonwebtoken": "^8.3.0",
  "nodemailer": "^4.6.7",
  "npm-run-all": "^4.1.3",
  "prisma": "^1.17.1",
  "prisma-binding": "^2.1.6"
},

if i install it i get

Error: Type generator exists in middleware but is missing in Schema.

If i remove graphql-shield from middlewares all is working.
Looks like some packages is conflict. But which.
Removing 'graphql-middleware-forward-binding' from middlewares it is don't cause any effect

Also then i yarn install i get some warnings:

warning " > [email protected]" has unmet peer dependency "graphql-middleware@^1.3.2".
warning "graphql-middleware-forward-binding > [email protected]" has incorrect peer dependency "graphql@^0.11.0 || ^0.12.0 || ^0.13.0".
warning "graphql-middleware-forward-binding > graphql-binding > [email protected]" has incorrect peer dependency "graphql@^0.11.0 || ^0.12.0 || ^0.13.0".
warning "prisma-binding > [email protected]" has incorrect peer dependency "graphql@^0.13.0".
warning " > [email protected]" has unmet peer dependency "graphql-middleware@^1.6.4".
warning "prisma > [email protected]" has incorrect peer dependency "graphql@^0.12.0 || ^0.13.0".
warning " > [email protected]" has incorrect peer dependency "graphql@^0.11.0 || ^0.12.0 || ^0.13.0".
warning "prisma-binding > [email protected]" has incorrect peer dependency "graphql@^0.11.3 || ^0.12.3 || ^0.13.0".
warning "prisma-binding > [email protected]" has incorrect peer dependency "graphql@^0.11.0 || ^0.12.0 || ^0.13.0".
warning "prisma-binding > [email protected]" has incorrect peer dependency "graphql@^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.1".
warning " > [email protected]" has incorrect peer dependency "typescript@^2.5.3".

GOTCHA!
Using graphql": "^0.13.2 don't cause any error.
And looks like i don't need this package, so i remove that and everything work.
Don't know why i installed it, but it is he who conflicts.

@heymartinadams
Copy link

heymartinadams commented Oct 9, 2018

Hi @maticzav! 💯

Receiving the same error — could it lie with my codebase?

Error: Type generator exists in middleware but is missing in Schema.
  "dependencies": {
    // ...
    "graphql-middleware": "^1.7.6",
    "graphql-shield": "^3.2.5",
    "graphql-yoga": "^1.13.1",
    "prisma-binding": "^2.1.6",
  },
  "devDependencies": {
    "graphql": "^0.13.2",
    // ...
  }

@maticzav
Copy link
Owner

Hey @heymartinadams, your graphql-yoga version is outdated.

@maticzav
Copy link
Owner

@kevrat perfect! I think we should add this to the README. graphql-middleware and graphql-yoga still haven't been updated to the latest GraphQL which might cause the issue that you are describing.

I am so glad it's working now 🎉

@heymartinadams
Copy link

Mmh, @maticzav, upgraded graphql-yoga to 1.16.2, but that error still appears. Could it perhaps be because I’ve moved the rules to another folder? (i.e. does the middleware still reach the rule()(async (parent, { email }, ctx, info) => { ...}) function?)

@maticzav
Copy link
Owner

Hey @heymartinadams 👋,

No, having rules in a separate folder is completely fine. Peeking at your package.json again, however, I spotted you have a separate instance of graphql-middleware alongside graphql-yoga. Try removing that as well.

@heymartinadams
Copy link

That totally did the trick, @maticzav 💛 Thanks a bunches!! Can’t wait to try and test it out ✨

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants