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

TypeError: resolver is not a function using apollo-server-micro latest version v3.0.1 #5517

Closed
deadcoder0904 opened this issue Jul 20, 2021 · 19 comments

Comments

@deadcoder0904
Copy link

I have an old project using apollo-server-micro@2.21.2 like:

export default handler().use(
  new ApolloServer({
    schema,
    context: ({ req }): GraphQLContext => ({
      user: req.user,
      origin: getRequestOrigin(req),
      prisma,
    }),
  }).createHandler({
    path: "/api",
  })
);

And it works 🎉

When I updated it to v3.0.1 & tried using the start method, I get Internal Server Error. For reference, this is my new updated code:

const apolloServer = new ApolloServer({
  schema,
  context: ({ req }): GraphQLContext => ({
    user: req.user,
    origin: getRequestOrigin(req),
    prisma,
  }),
  plugins: [ApolloServerPluginLandingPageGraphQLPlayground({})],
});

export default apolloServer.start().then(() => {
  return handler().use(
    apolloServer.createHandler({
      path: "/api",
    })
  );
});

How do I solve it with the latest version? Others are also facing the same issue :(

@glasser
Copy link
Member

glasser commented Jul 20, 2021

I responded on the Reddit thread, but that looks like a different issue than what you're describing.

I'd love to help you solve your problem, but it's not possible unless I can reproduce it on my own machine. Can you create a minimal reproduction (eg, something I can git clone or play around with in codesandbox.io) that demonstrates the issue? I'll be happy to re-open this issue if you can.

@glasser glasser closed this as completed Jul 20, 2021
@deadcoder0904
Copy link
Author

deadcoder0904 commented Jul 21, 2021

Unfortunately, it's a big private repo. Here's a similar repo found through SourceGraph's awesome search -> https://gitlab.com/yo/devparty

Check this file -> https://gitlab.com/yo/devparty/-/blob/main/src/pages/api/index.ts#L19-30

Try running the project using yarn.

Then docker-compose up in 1 terminal & yarn dev in another terminal simultaneously.

It should run. Then try installing the latest apollo-server-micro using npm i apollo-server-micro@latest & see the errors.

It'll yell to use start which I did but then got lost. Try opening localhost:3000/api to see it say Internal Server Error when I do the above thing but works on the previous version (see previous comment for the related code)

@glasser
Copy link
Member

glasser commented Jul 21, 2021

Can you make your own fork of this that shows your work, so I don't have to guess what you mean by "which I did"?

@deadcoder0904
Copy link
Author

deadcoder0904 commented Jul 22, 2021

It's exactly the same thing, man. I've tried it myself.

By "which I did", I mean I did use start() as you can see in the 2nd code-block in this comment. See apolloServer.start() :)

The thing is I only need to get it to work like the 1st code-block that uses an older version. I read through the whole docs & tried different variations but was unable to get it to work.

@deadcoder0904
Copy link
Author

deadcoder0904 commented Jul 22, 2021

@glasser I've made a simple demo here that works on older version -> https://stackblitz.com/edit/nextjs-nt4pub?file=pages%2Fapi%2Findex.js

Click on Open in New Window at the top-right in Stackblitz & go to /api to see Hello World.

Try changing apollo-server-micro in package.json to 3.0.2 & stop & start the server again using npm install && npx next dev so it installs the new package. Go to /api again & see the new error. Then let me know how to go forward :)

@osadchiynikita
Copy link

+1 I have same issue with v3, but works as expected with v2

@sachinraja
Copy link

sachinraja commented Jul 23, 2021

+1, am getting same error. Tested with the official Next.js api-routes-apollo-server example too. Repro here. npm install, npm run dev, and then go to localhost:3000/api/graphql.

@lukin
Copy link

lukin commented Jul 23, 2021

I came across a similar error. Try the updated example.

@sachinraja
Copy link

sachinraja commented Jul 23, 2021

@lukin, thanks for sharing. That works great on the same origin, but I was unable to query it on apollo studio. I fixed it by using this in the handler:

const handler: NextApiHandler = async (req, res) => {
  res.setHeader('Access-Control-Allow-Credentials', 'true')
  res.setHeader('Access-Control-Allow-Origin', '*')
  res.setHeader(
    'Access-Control-Allow-Methods',
    'GET,OPTIONS,PATCH,DELETE,POST,PUT',
  )
  res.setHeader(
    'Access-Control-Allow-Headers',
    'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version',
  )

  if (req.method === 'OPTIONS') return res.end()

  await startServer
  await server.createHandler({
    path: '/api/graphql',
  })(req, res)

  return res.end()
}

export default handler

as per Vercel's cors docs.

You can also use micro-cors:

import Cors from 'micro-cors'

const cors = Cors()

const handler: NextApiHandler = async (req, res) => {
if (req.method === 'OPTIONS') return res.end()

await startServer
await server.createHandler({
  path: '/api/graphql',
})(req, res)

return res.end()
}

// @ts-expect-error these are compatible
export default cors(handler)

@deadcoder0904
Copy link
Author

@lukin @sachinraja any idea how to fix mine -> #5517 (comment)

@sachinraja
Copy link

sachinraja commented Jul 24, 2021

@deadcoder0904 should work the same way:

const apiHandler: NextApiHandler = async (req, res) => {
if (req.method === 'OPTIONS') return res.end()

await startServer
const ncHandler = handler.use(server.createHandler({
  path: '/api/graphql',
}))

await ncHandler.run(req, res)

return res.end()
}

export default apiHandler

@deadcoder0904
Copy link
Author

@sachinraja confused what is startServer? also, where do I put this? can you edit this stackblitz & share? Just need to put this code in the correct place.

@sachinraja
Copy link

sachinraja commented Jul 24, 2021

@deadcoder0904 I am not sure how to alter that, there are two default exports. startServer is const startServer = server.start(), called outside the handler.

@deadcoder0904
Copy link
Author

@sachinraja Thank you. I managed to make it work thanks to you & SourceGraph's search again.

Had to do it like this:

const apolloServer = new ApolloServer({
  typeDefs,
  resolvers
});

export default handler().use(async (req, res) => {
  await apolloServer.start();
  await apolloServer.createHandler({
    path: '/api'
  });
});

@sachinraja
Copy link

sachinraja commented Jul 24, 2021

@deadcoder0904 that shouldn't work, you are supposed to start the server only once, outside the handler.

@deadcoder0904
Copy link
Author

Alright, I'll put that out but it does work on Stackblitz maybe because Stackblitz runs in isolated context but I'll see it in my app or put it out :)

@glasser
Copy link
Member

glasser commented Aug 3, 2021

@sachinraja Hi, I tried to follow the directions in #5517 (comment) but it looks like you already edited the project away from the example of what doesn't work, so I'm not able to help. (I'm on and off vacation this month, thus the delay.)

Also as I mentioned today in #5547 (comment) — I am personally incredibly confused by the relationship between Micro and Next. I see there are many people coming to this repo confused that apollo-server-micro doesn't work in Next... but when I try to do basic research like looking at the Next.js website and Wikipedia page for references to Micro, or look at the Micro README for references to Next.js, I find nothing. I don't really understand where the expectation that apollo-server-micro will work with Next.js comes from?

@deadcoder0904
Copy link
Author

@glasser I think Next.js used or used to use micro early on & a bunch of projects picked up on it & it's now everywhere.

This is a case similar to Redux. Better state-management libraries exist but since the Internet is filled with tutorials of it, everyone uses it :)

@sachinraja
Copy link

sachinraja commented Aug 3, 2021

@glasser the repro of the issue is unrelated to the connection between Next.js and apollo-server-micro and has since been resolved (see #5517 (comment). Next.js has a working example here, which is essentially the same as what I recommended. About the connection between the two, I think this is an issue on Next.js's side. They really need to clarify it as I am confused as well. Everyone is using micro because Next.js uses it in their examples, yet they says it's not meant for serverless environments.

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

No branches or pull requests

5 participants