Skip to content

Commit 3324bba

Browse files
Unique execution context with the correct request object (#3237)
* Unique execution context with the correct request object * Changeset * chore(dependencies): updated changesets for modified dependencies * Prettier --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 58d3512 commit 3324bba

File tree

6 files changed

+89
-17
lines changed

6 files changed

+89
-17
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'graphql-yoga': patch
3+
---
4+
dependencies updates:
5+
- Updated dependency [`@whatwg-node/server@^0.9.33`
6+
↗︎](https://www.npmjs.com/package/@whatwg-node/server/v/0.9.33) (from `^0.9.32`, in
7+
`dependencies`)

.changeset/smart-melons-beam.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'graphql-yoga': patch
3+
---
4+
5+
In such environments like CloudFlare Workers, the `request` object in the context always has the initial request object, so it was impossible to access the actual `Request` object from the execution context.
6+
Now Yoga ensures that the `request` in the context is the same with the actual `Request`.

packages/graphql-yoga/__tests__/requests.spec.ts

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { createSchema, createYoga } from '../src';
1+
import { OnExecuteHook } from '@envelop/core';
2+
import { Request } from '@whatwg-node/fetch';
3+
import { createSchema, createYoga, YogaInitialContext } from '../src';
24

35
describe('requests', () => {
46
const schema = createSchema({
@@ -453,4 +455,60 @@ describe('requests', () => {
453455
const body = await response.text();
454456
expect(body).toBeFalsy();
455457
});
458+
459+
it('contains the correct request object in the unique execution context', async () => {
460+
const onExecuteFn = jest.fn((() => {}) as OnExecuteHook<YogaInitialContext>);
461+
const yoga = createYoga({
462+
schema: createSchema({
463+
typeDefs: /* GraphQL */ `
464+
type Query {
465+
greetings: String
466+
}
467+
`,
468+
resolvers: {
469+
Query: {
470+
greetings: (_, __, ctx) => {
471+
return `Hello world!`;
472+
},
473+
},
474+
},
475+
}),
476+
plugins: [
477+
{
478+
onExecute: onExecuteFn,
479+
},
480+
],
481+
});
482+
const env = {};
483+
const extraCtx = {};
484+
const firstReq = new Request('http://yoga/graphql', {
485+
method: 'POST',
486+
headers: {
487+
'content-type': 'application/json',
488+
},
489+
body: JSON.stringify({ query: '{ greetings }' }),
490+
});
491+
const firstRes = await yoga.fetch(firstReq, env, extraCtx);
492+
expect(firstRes.status).toBe(200);
493+
const firstResBody = await firstRes.json();
494+
expect(firstResBody.data.greetings).toBe('Hello world!');
495+
expect(onExecuteFn).toHaveBeenCalledTimes(1);
496+
expect(onExecuteFn.mock.calls[0][0].args.contextValue.request).toBe(firstReq);
497+
const secondReq = new Request('http://yoga/graphql', {
498+
method: 'POST',
499+
headers: {
500+
'content-type': 'application/json',
501+
},
502+
body: JSON.stringify({ query: '{ greetings }' }),
503+
});
504+
const secondRes = await yoga.fetch(secondReq, env, extraCtx);
505+
expect(secondRes.status).toBe(200);
506+
const secondResBody = await secondRes.json();
507+
expect(secondResBody.data.greetings).toBe('Hello world!');
508+
expect(onExecuteFn).toHaveBeenCalledTimes(2);
509+
expect(onExecuteFn.mock.calls[1][0].args.contextValue.request).toBe(secondReq);
510+
expect(onExecuteFn.mock.calls[1][0].args.contextValue).not.toBe(
511+
onExecuteFn.mock.calls[0][0].args.contextValue,
512+
);
513+
});
456514
});

packages/graphql-yoga/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
"@graphql-yoga/logger": "^2.0.0",
5757
"@graphql-yoga/subscription": "^5.0.0",
5858
"@whatwg-node/fetch": "^0.9.17",
59-
"@whatwg-node/server": "^0.9.32",
59+
"@whatwg-node/server": "^0.9.33",
6060
"dset": "^3.1.1",
6161
"lru-cache": "^10.0.0",
6262
"tslib": "^2.5.2"

packages/graphql-yoga/src/server.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -463,14 +463,15 @@ export class YogaServer<
463463
}
464464

465465
if (result == null) {
466-
const additionalContext = args[0]?.request
467-
? {
468-
params,
469-
}
470-
: {
471-
request,
472-
params,
473-
};
466+
const additionalContext =
467+
args[0]?.request === request
468+
? {
469+
params,
470+
}
471+
: {
472+
request,
473+
params,
474+
};
474475

475476
const initialContext = args[0]
476477
? batched

pnpm-lock.yaml

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)