Skip to content

Commit

Permalink
fix: do not return 404s when trailing slashes or query params are in …
Browse files Browse the repository at this point in the history
…the url (#3120)

Co-authored-by: Antonio Iodice <antonioiodice92@gmail.com>
  • Loading branch information
antonio-iodice and Antonio Iodice authored Nov 30, 2023
1 parent d1cfe5b commit 3fea19f
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/healthy-ghosts-look.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'graphql-yoga': patch
---

Do not return 404 when using query params or trailing slashes
36 changes: 36 additions & 0 deletions packages/graphql-yoga/__tests__/requests.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,42 @@ describe('requests', () => {
expect(body.data.requestUrl).toBe('http://yoga/v1/mypath');
});

it('supports trailing slash in url', async () => {
const yoga = createYoga({
schema,
logging: false,
graphqlEndpoint: '/graphql',
});
const response = await yoga.fetch('http://yoga/graphql/', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ query: '{ requestUrl }' }),
});

expect(response.status).toBe(200);
const body = await response.json();
expect(body.errors).toBeUndefined();
expect(body.data.requestUrl).toBe('http://yoga/graphql/');
});

it('supports query params in url', async () => {
const yoga = createYoga({
schema,
logging: false,
graphqlEndpoint: '/graphql',
});
const response = await yoga.fetch('http://yoga/graphql?query=something+awesome', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ query: '{ requestUrl }' }),
});

expect(response.status).toBe(200);
const body = await response.json();
expect(body.errors).toBeUndefined();
expect(body.data.requestUrl).toBe('http://yoga/graphql?query=something+awesome');
});

it('allows you to bypass endpoint check with wildcard', async () => {
const yoga = createYoga({
schema,
Expand Down
28 changes: 28 additions & 0 deletions packages/graphql-yoga/src/plugins/use-graphiql.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,33 @@ describe('GraphiQL', () => {
expect(response.headers.get('content-type')).not.toEqual('text/html');
expect(response.status).toEqual(406);
});

it('returns graphiql when passing query params and trailing slash', async () => {
const yoga = createYoga({
graphiql: () => Promise.resolve({ title: 'Test GraphiQL' }),
});
const responseWithQueryParams = await yoga.fetch(
'http://localhost:3000/graphql?query=something+awesome',
{
method: 'GET',
headers: {
Accept: 'text/html',
},
},
);
expect(responseWithQueryParams.headers.get('content-type')).toEqual('text/html');
const resultWithQueryParams = await responseWithQueryParams.text();
expect(resultWithQueryParams).toMatch(/<title>Test GraphiQL<\/title>/);

const responseWithTrailingSlash = await yoga.fetch('http://localhost:3000/graphql/', {
method: 'GET',
headers: {
Accept: 'text/html',
},
});
expect(responseWithTrailingSlash.headers.get('content-type')).toEqual('text/html');
const resultWithTrailingSlash = await responseWithTrailingSlash.text();
expect(resultWithTrailingSlash).toMatch(/<title>Test GraphiQL<\/title>/);
});
});
});
4 changes: 3 additions & 1 deletion packages/graphql-yoga/src/plugins/use-graphiql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,11 @@ export function useGraphiQL<TServerContext extends Record<string, any>>(
};
return {
async onRequest({ request, serverContext, fetchAPI, endResponse, url }) {
const requestedUrl = request.url.split('?')[0];
if (
shouldRenderGraphiQL(request) &&
(request.url.endsWith(config.graphqlEndpoint) ||
(requestedUrl.endsWith(config.graphqlEndpoint) ||
requestedUrl.endsWith(`${config.graphqlEndpoint}/`) ||
url.pathname === config.graphqlEndpoint ||
getUrlPattern(fetchAPI).test(url))
) {
Expand Down
4 changes: 3 additions & 1 deletion packages/graphql-yoga/src/plugins/use-unhandled-route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ export function useUnhandledRoute(args: {
}
return {
onRequest({ request, fetchAPI, endResponse, url }) {
const requestedUrl = request.url.split('?')[0];
if (
!request.url.endsWith(args.graphqlEndpoint) &&
!requestedUrl.endsWith(args.graphqlEndpoint) &&
!requestedUrl.endsWith(`${args.graphqlEndpoint}/`) &&
url.pathname !== args.graphqlEndpoint &&
!getUrlPattern(fetchAPI).test(url)
) {
Expand Down

0 comments on commit 3fea19f

Please sign in to comment.