dotansimha / graphql-yoga

🧘 Rewrite of a fully-featured GraphQL Server with focus on easy setup, performance & great developer experience. The core of Yoga implements WHATWG Fetch API and can run/deploy on any JS environment.
https://the-guild.dev/graphql/yoga-server
MIT License
8.25k stars 573 forks source link

Vercel Edge Runtime support #2247

Open alvarlagerlof opened 1 year ago

alvarlagerlof commented 1 year ago

Is your feature request related to a problem? Please describe.

Support for using the Vercel Edge runtime with Next.js.

Describe the solution you'd like

Integration from the library, like how api routes work now.

ardatan commented 1 year ago

We don't introduce integration packages for each platform. We use Fetch API just like Vercel Edge does. When I check the documentation, I see that it needs a function that takes Request and returns Response so it should be simple as;

import { createYoga, createSchema } from 'graphql-yoga'

export const config = {
  runtime: 'edge',
};

const yoga = createYoga({
  schema: createSchema({
    typeDefs: /* GraphQL */ `
      type Query {
        greetings: String!
      }
    `,
    resolvers: {
      Query: {
        greetings: () =>
          'This is the `greetings` field of the root `Query` type',
      },
    },
  }),
})

export default yoga
alvarlagerlof commented 1 year ago

Working great, although I did have to remap it to a NextResponse.

n1ru4l commented 1 year ago

Would be great if we have an example with integration tests in this repo.

sigginjals commented 1 year ago

@alvarlagerlof How did you map it to NextReponse?

ardatan commented 1 year ago

What kind of remapping do you mean? NextResponse is also Response like Yoga returns right? So isn't it working as expected?

sigginjals commented 1 year ago

Yes, I'm having some issues. If I copy and paste the code above into a file called /api/graphql.ts (I did add the graphqlEndpoint config to match the URL).

I keep getting this error:

image

I tried wrapping the handler like this:

const handler = async (request: Request): Promise<Response> => {
  return await yoga.handleRequest(request, {});
};

That works better, but I get an error in Vercel saying: URLPattern is not a constructor

Did you not have to do anything else than copy the code above? What version of Next are you running?

alvarlagerlof commented 1 year ago

I ended up using yoga.fetch() and then creating a NextResponse and passing in text and the status.

sigginjals commented 1 year ago

Polyfilling URLPattern did the trick, no idea why, Vercel says edge functions support URLPattern. I might try the fetch as-well.

n1ru4l commented 1 year ago

Hey @sigginjals @alvarlagerlof, I am working on adding an end2end integration test in https://github.com/dotansimha/graphql-yoga/pull/2471 to ensure a smooth integration.