From 185d4702ac46a990fc572b8042e877c18c7b5353 Mon Sep 17 00:00:00 2001 From: Nicolas Escalante Date: Mon, 26 Jun 2023 20:58:05 -0300 Subject: [PATCH] do not return 404 when using query params or trailing slash --- .../graphql-yoga/src/plugins/plugins.test.ts | 2 +- .../src/plugins/use-graphiql.spec.ts | 18 ++++++++++++++++++ .../graphql-yoga/src/plugins/use-graphiql.ts | 3 ++- .../src/plugins/use-unhandled-route.ts | 3 ++- packages/graphql-yoga/src/utils/url.ts | 6 ++++++ 5 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 packages/graphql-yoga/src/utils/url.ts diff --git a/packages/graphql-yoga/src/plugins/plugins.test.ts b/packages/graphql-yoga/src/plugins/plugins.test.ts index c4ebbf19c5..5d85204408 100644 --- a/packages/graphql-yoga/src/plugins/plugins.test.ts +++ b/packages/graphql-yoga/src/plugins/plugins.test.ts @@ -35,7 +35,7 @@ describe('Yoga Plugins', () => { plugins: [testPluginToAdd], schema, }) - const response = await yoga.fetch('http://localhost:3000/graphql', { + const response = await yoga.fetch('http://localhost:3000/graphql/', { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/packages/graphql-yoga/src/plugins/use-graphiql.spec.ts b/packages/graphql-yoga/src/plugins/use-graphiql.spec.ts index 840cb74337..53b0e58bbe 100644 --- a/packages/graphql-yoga/src/plugins/use-graphiql.spec.ts +++ b/packages/graphql-yoga/src/plugins/use-graphiql.spec.ts @@ -17,6 +17,24 @@ describe('GraphiQL', () => { expect(result).toMatch(/Test GraphiQL<\/title>/) }) + it('renders graphiql when passing query params and trailing slash', async () => { + const yoga = createYoga({ + graphiql: () => Promise.resolve({ title: 'Test GraphiQL' }), + }) + const response = await yoga.fetch( + 'http://localhost:3000/graphql/?query=something+awesome', + { + method: 'GET', + headers: { + Accept: 'text/html', + }, + }, + ) + expect(response.headers.get('content-type')).toEqual('text/html') + const result = await response.text() + expect(result).toMatch(/<title>Test GraphiQL<\/title>/) + }) + it('returns error when graphiql is disabled', async () => { const yoga = createYoga({ graphiql: () => Promise.resolve(false), diff --git a/packages/graphql-yoga/src/plugins/use-graphiql.ts b/packages/graphql-yoga/src/plugins/use-graphiql.ts index 5984cc9648..2e6f1e2a1a 100644 --- a/packages/graphql-yoga/src/plugins/use-graphiql.ts +++ b/packages/graphql-yoga/src/plugins/use-graphiql.ts @@ -3,6 +3,7 @@ import graphiqlHTML from '../graphiql-html.js' import { YogaLogger } from '@graphql-yoga/logger' import { FetchAPI } from '../types.js' import { Plugin } from './types.js' +import { isGraphqlEndpoint } from '../utils/url.js' export function shouldRenderGraphiQL({ headers, method }: Request): boolean { return method === 'GET' && !!headers?.get('accept')?.includes('text/html') @@ -100,7 +101,7 @@ export function useGraphiQL<TServerContext extends Record<string, any>>( async onRequest({ request, serverContext, fetchAPI, endResponse, url }) { if ( shouldRenderGraphiQL(request) && - (request.url.endsWith(config.graphqlEndpoint) || + (isGraphqlEndpoint(request.url, config.graphqlEndpoint) || url.pathname === config.graphqlEndpoint || getUrlPattern(fetchAPI).test(url)) ) { diff --git a/packages/graphql-yoga/src/plugins/use-unhandled-route.ts b/packages/graphql-yoga/src/plugins/use-unhandled-route.ts index 759a552e99..8c83743eb6 100644 --- a/packages/graphql-yoga/src/plugins/use-unhandled-route.ts +++ b/packages/graphql-yoga/src/plugins/use-unhandled-route.ts @@ -1,4 +1,5 @@ import landingPageBody from '../landing-page-html.js' +import { isGraphqlEndpoint } from '../utils/url.js' import { FetchAPI } from '../types.js' import type { Plugin } from './types.js' @@ -16,7 +17,7 @@ export function useUnhandledRoute(args: { return { onRequest({ request, fetchAPI, endResponse, url }) { if ( - !request.url.endsWith(args.graphqlEndpoint) && + !isGraphqlEndpoint(request.url, args.graphqlEndpoint) && url.pathname !== args.graphqlEndpoint && !getUrlPattern(fetchAPI).test(url) ) { diff --git a/packages/graphql-yoga/src/utils/url.ts b/packages/graphql-yoga/src/utils/url.ts new file mode 100644 index 0000000000..f9c200ab5b --- /dev/null +++ b/packages/graphql-yoga/src/utils/url.ts @@ -0,0 +1,6 @@ +export function isGraphqlEndpoint(url: string, graphqlEndpoint: string) { + const urlWithoutQuery = url.split('?')[0] + const normalizedUrl = urlWithoutQuery.replace(/\/$/, '') + + return normalizedUrl.endsWith(graphqlEndpoint) +}