From 185d4702ac46a990fc572b8042e877c18c7b5353 Mon Sep 17 00:00:00 2001 From: Nicolas Escalante Date: Mon, 26 Jun 2023 20:58:05 -0300 Subject: [PATCH 1/4] 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) +} From adb12605fedb7450d64ca674cb86ff3029094b72 Mon Sep 17 00:00:00 2001 From: Nicolas Escalante <nlante@gmail.com> Date: Mon, 26 Jun 2023 21:06:06 -0300 Subject: [PATCH 2/4] add changeset --- .changeset/flat-tips-look.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/flat-tips-look.md diff --git a/.changeset/flat-tips-look.md b/.changeset/flat-tips-look.md new file mode 100644 index 0000000000..e78d289c73 --- /dev/null +++ b/.changeset/flat-tips-look.md @@ -0,0 +1,5 @@ +--- +'graphql-yoga': patch +--- + +do not return 404 when using query params or trailing slash From 75380b39416e8056daadf6df418b2cb5a91d90e1 Mon Sep 17 00:00:00 2001 From: Nicolas Escalante <nlante@gmail.com> Date: Tue, 27 Jun 2023 14:28:32 -0300 Subject: [PATCH 3/4] leave query params ignore on;y --- packages/graphql-yoga/src/plugins/plugins.test.ts | 2 +- packages/graphql-yoga/src/plugins/use-graphiql.spec.ts | 2 +- packages/graphql-yoga/src/plugins/use-graphiql.ts | 3 +-- packages/graphql-yoga/src/plugins/use-unhandled-route.ts | 3 +-- packages/graphql-yoga/src/utils/url.ts | 6 ------ 5 files changed, 4 insertions(+), 12 deletions(-) delete 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 5d85204408..c4ebbf19c5 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 53b0e58bbe..8c819990ab 100644 --- a/packages/graphql-yoga/src/plugins/use-graphiql.spec.ts +++ b/packages/graphql-yoga/src/plugins/use-graphiql.spec.ts @@ -22,7 +22,7 @@ describe('GraphiQL', () => { graphiql: () => Promise.resolve({ title: 'Test GraphiQL' }), }) const response = await yoga.fetch( - 'http://localhost:3000/graphql/?query=something+awesome', + 'http://localhost:3000/graphql?query=something+awesome', { method: 'GET', headers: { diff --git a/packages/graphql-yoga/src/plugins/use-graphiql.ts b/packages/graphql-yoga/src/plugins/use-graphiql.ts index 2e6f1e2a1a..e7ee624bbe 100644 --- a/packages/graphql-yoga/src/plugins/use-graphiql.ts +++ b/packages/graphql-yoga/src/plugins/use-graphiql.ts @@ -3,7 +3,6 @@ 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') @@ -101,7 +100,7 @@ export function useGraphiQL<TServerContext extends Record<string, any>>( async onRequest({ request, serverContext, fetchAPI, endResponse, url }) { if ( shouldRenderGraphiQL(request) && - (isGraphqlEndpoint(request.url, config.graphqlEndpoint) || + (request.url.split('?')[0].endsWith(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 8c83743eb6..759a552e99 100644 --- a/packages/graphql-yoga/src/plugins/use-unhandled-route.ts +++ b/packages/graphql-yoga/src/plugins/use-unhandled-route.ts @@ -1,5 +1,4 @@ import landingPageBody from '../landing-page-html.js' -import { isGraphqlEndpoint } from '../utils/url.js' import { FetchAPI } from '../types.js' import type { Plugin } from './types.js' @@ -17,7 +16,7 @@ export function useUnhandledRoute(args: { return { onRequest({ request, fetchAPI, endResponse, url }) { if ( - !isGraphqlEndpoint(request.url, args.graphqlEndpoint) && + !request.url.endsWith(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 deleted file mode 100644 index f9c200ab5b..0000000000 --- a/packages/graphql-yoga/src/utils/url.ts +++ /dev/null @@ -1,6 +0,0 @@ -export function isGraphqlEndpoint(url: string, graphqlEndpoint: string) { - const urlWithoutQuery = url.split('?')[0] - const normalizedUrl = urlWithoutQuery.replace(/\/$/, '') - - return normalizedUrl.endsWith(graphqlEndpoint) -} From 7aba56b64cbd41089b43a20f6662de933dde4904 Mon Sep 17 00:00:00 2001 From: Nicolas Escalante <nlante@gmail.com> Date: Tue, 27 Jun 2023 14:29:13 -0300 Subject: [PATCH 4/4] update changelog --- .changeset/flat-tips-look.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/flat-tips-look.md b/.changeset/flat-tips-look.md index e78d289c73..9e4669f2d0 100644 --- a/.changeset/flat-tips-look.md +++ b/.changeset/flat-tips-look.md @@ -2,4 +2,4 @@ 'graphql-yoga': patch --- -do not return 404 when using query params or trailing slash +do not return 404 when using query params for graphiql