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

[v3] Bypass GraphQL endpoint checking #2132

Closed
Tracked by #1358
koichik opened this issue Nov 20, 2022 · 7 comments · Fixed by #2266, #2273 or #2275
Closed
Tracked by #1358

[v3] Bypass GraphQL endpoint checking #2132

koichik opened this issue Nov 20, 2022 · 7 comments · Fixed by #2266, #2273 or #2275

Comments

@koichik
Copy link

koichik commented Nov 20, 2022

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

Yoga v3 introduces the graphqlEndpoint option, but it seems there is no way to bypass the endpoint URL checking.
We use the Next.js API routes to mount Yoga on the following URL:

/api/graphql/[operationName]

Actually, [operationName] part is not used in our application, but it is useful for monitoring etc.
However, Yoga v3 simply compares the graphqlEndpoint option to the URL, so it can not handle URLs with dynamic paths like this anymore.
In practice, the API route in Next.js is only called if the URL matches, so the additional endpoint checking by Yoga is not necessary I think.

Describe the solution you'd like

Could you consider adding a way to bypass the endpoint checking?
For example: graphqlEndpoint: false

Describe alternatives you've considered

Support for path-to-regex, such as graphqlEndpoint: 'api/graphql/:operationName'

Additional context

Workaround currently in use:

    const url = new URL(req.url!, `http://${req.headers.host}`)
    req.url = '/api/graphql' + url.search
    await yogaServer(req, res)
@n1ru4l
Copy link
Collaborator

n1ru4l commented Nov 21, 2022

What if graphqlEndpoint accepts a function that returns a boolean? 🤔

This might then also be capable of handling the /graphql/sha-hash use-case for persisted operations. 🤔

const plugin = {
  async onRequestParse(ctx) {
    const url = new URL(ctx.request.url)

    if (url.pathname.startsWith('/graphql/')) {
      const documentSha = url.pathname.replace('/graphql/', '')

      return {
        async onRequestParseDone(ctx) {
          if (Array.isArray(ctx.requestParserResult)) {
            return
          }
          const query = await store.load(documentSha)

          ctx.setRequestParserResult({
            extensions: ctx.requestParserResult.extensions,
            query,
            variables: ctx.requestParserResult.variables,
          })
        },
      }
    }
  },
};

const yoga = createYoga({
  graphqlEndpoint: (url) => url.startsWith("/graphql"),
  plugins: [plugin],
});

This would probably be a breaking change for the yoga.graphqlEndpoint property.

Maybe we could instead allow from within a plugin to overwrite the check for whether a request should hit the graphql.layer

@koichik
Copy link
Author

koichik commented Nov 21, 2022

Thanks for your response!

What if graphqlEndpoint accepts a function that returns a boolean? 🤔

Make sense, it's very extensible!

@ozmuir
Copy link

ozmuir commented Dec 7, 2022

I have a related issue (may be related to GraphiQL in part). I want to serve it from /api/v1/graphql where the /api/v1 prefix is to be transparently removed by my proxy server and the app be completely unaware of the prefix. So I have

const yoga = createYoga<{ req: FastifyRequest; reply: FastifyReply }>({ ..., graphqlEndpoint: "/graphql" })

and GraphiQL UI is loading on /api/v1/graphql, but then it is sending request to /graphql and is unable to load models. Currently working around it by rewriting the URL in the GraphiQL HTML from {"endpoint":"/graphql"}) to {"endpoint":"/api/v1/graphql"}). Would love to learn how to force GraphiQL to just use the page URL for GraphQL requests.

@elitan
Copy link

elitan commented Jan 2, 2023

We have the same issue at Nhost.

In our CLI, Functions are served at http://localhost:1337/v1/functions/[file-name] e.g. http://localhost:1337/v1/functions/graphql and /v1/functions is removed by Traefik internally.

In production, the endpoint is different, like this: https://flbqeqdulqcphrsxgxmg.functions.eu-central-1.nhost.run/v1/graphql. Again /v1 is removed by our proxy server.

Currently, GraphQL Yoga v3 is unusable on Nhost.

This was not an issue with GraphQL Yoga v2.

@ardatan
Copy link
Collaborator

ardatan commented Jan 2, 2023

#2266
With this PR, graphqlEndpoint starts supporting url patterns like *.
You can start using it with the canaries until it gets released.

@elitan
Copy link

elitan commented Jan 2, 2023

@ardatan That worked great; the GraphQL API is now working with graphqlEndpoint: "*"

But now, there is an issue with GraphiQL. Should we create a separate issue for it?

CleanShot 2023-01-02 at 13 43 17

@ardatan
Copy link
Collaborator

ardatan commented Jan 3, 2023

Should be fixed in 3.3.1
@elitan

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment