Skip to content

Commit d86318a

Browse files
committed
feat: Change GraphQL acceptable media type application/graphql+json to application/graphql-response+json
As per graphql/graphql-over-http#215
1 parent 58a0411 commit d86318a

File tree

4 files changed

+36
-36
lines changed

4 files changed

+36
-36
lines changed

docs/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ val is Response
104104

105105
### AcceptableMediaType
106106

107-
Ƭ **AcceptableMediaType**: ``"application/graphql+json"`` \| ``"application/json"``
107+
Ƭ **AcceptableMediaType**: ``"application/graphql-response+json"`` \| ``"application/json"``
108108

109109
Request's Media-Type that the server accepts.
110110

src/__tests__/server.ts

+27-27
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ beforeAll(() => {
1010
});
1111

1212
describe('Media Types', () => {
13-
it('must accept application/graphql+json and match the content-type', async () => {
13+
it('must accept application/graphql-response+json and match the content-type', async () => {
1414
const url = new URL(serverUrl);
1515
url.searchParams.set('query', '{ __typename }');
1616

1717
const res = await fetch(url.toString(), {
1818
headers: {
19-
accept: 'application/graphql+json',
19+
accept: 'application/graphql-response+json',
2020
},
2121
});
2222
expect(res.status).toBe(200);
2323
expect(res.headers.get('content-type')).toContain(
24-
'application/graphql+json',
24+
'application/graphql-response+json',
2525
);
2626
});
2727

@@ -38,7 +38,7 @@ describe('Media Types', () => {
3838
expect(res.headers.get('content-type')).toContain('application/json');
3939
});
4040

41-
it('must accept */* and use application/graphql+json for the content-type', async () => {
41+
it('must accept */* and use application/graphql-response+json for the content-type', async () => {
4242
const url = new URL(serverUrl);
4343
url.searchParams.set('query', '{ __typename }');
4444

@@ -49,18 +49,18 @@ describe('Media Types', () => {
4949
});
5050
expect(res.status).toBe(200);
5151
expect(res.headers.get('content-type')).toContain(
52-
'application/graphql+json',
52+
'application/graphql-response+json',
5353
);
5454
});
5555

56-
it('must assume application/graphql+json content-type when accept is missing', async () => {
56+
it('must assume application/graphql-response+json content-type when accept is missing', async () => {
5757
const url = new URL(serverUrl);
5858
url.searchParams.set('query', '{ __typename }');
5959

6060
const res = await fetch(url.toString());
6161
expect(res.status).toBe(200);
6262
expect(res.headers.get('content-type')).toContain(
63-
'application/graphql+json',
63+
'application/graphql-response+json',
6464
);
6565
});
6666

@@ -79,7 +79,7 @@ describe('Media Types', () => {
7979

8080
const res = await fetch(url.toString(), {
8181
headers: {
82-
accept: 'application/graphql+json; charset=iso-8859-1',
82+
accept: 'application/graphql-response+json; charset=iso-8859-1',
8383
},
8484
});
8585
expect(res.status).toBe(406);
@@ -112,7 +112,7 @@ describe('Request', () => {
112112

113113
const res = await fetch(url.toString(), {
114114
headers: {
115-
accept: 'application/graphql+json',
115+
accept: 'application/graphql-response+json',
116116
},
117117
});
118118
expect(res.status).toBe(405);
@@ -152,7 +152,7 @@ describe('Request', () => {
152152
method: 'POST',
153153
headers: {
154154
'content-type': 'application/json',
155-
accept: 'application/graphql+json',
155+
accept: 'application/graphql-response+json',
156156
},
157157
body: JSON.stringify({ notquery: '{ __typename }' }),
158158
});
@@ -165,7 +165,7 @@ describe('Request', () => {
165165
method: 'POST',
166166
headers: {
167167
'content-type': 'application/json',
168-
accept: 'application/graphql+json',
168+
accept: 'application/graphql-response+json',
169169
},
170170
body: JSON.stringify({
171171
query: invalid,
@@ -179,7 +179,7 @@ describe('Request', () => {
179179
method: 'POST',
180180
headers: {
181181
'content-type': 'application/json',
182-
accept: 'application/graphql+json',
182+
accept: 'application/graphql-response+json',
183183
},
184184
body: JSON.stringify({
185185
query: '{ __typename }',
@@ -195,7 +195,7 @@ describe('Request', () => {
195195
method: 'POST',
196196
headers: {
197197
'content-type': 'application/json',
198-
accept: 'application/graphql+json',
198+
accept: 'application/graphql-response+json',
199199
},
200200
body: JSON.stringify({
201201
operationName: invalid,
@@ -210,7 +210,7 @@ describe('Request', () => {
210210
method: 'POST',
211211
headers: {
212212
'content-type': 'application/json',
213-
accept: 'application/graphql+json',
213+
accept: 'application/graphql-response+json',
214214
},
215215
body: JSON.stringify({
216216
operationName: 'Query',
@@ -227,7 +227,7 @@ describe('Request', () => {
227227
method: 'POST',
228228
headers: {
229229
'content-type': 'application/json',
230-
accept: 'application/graphql+json',
230+
accept: 'application/graphql-response+json',
231231
},
232232
body: JSON.stringify({
233233
query: '{ __typename }',
@@ -242,7 +242,7 @@ describe('Request', () => {
242242
method: 'POST',
243243
headers: {
244244
'content-type': 'application/json',
245-
accept: 'application/graphql+json',
245+
accept: 'application/graphql-response+json',
246246
},
247247
body: JSON.stringify({
248248
query: 'query Type($name: String!) { __type(name: $name) { name } }',
@@ -275,7 +275,7 @@ describe('Request', () => {
275275
method: 'POST',
276276
headers: {
277277
'content-type': 'application/json',
278-
accept: 'application/graphql+json',
278+
accept: 'application/graphql-response+json',
279279
},
280280
body: JSON.stringify({
281281
query: '{ __typename }',
@@ -290,7 +290,7 @@ describe('Request', () => {
290290
method: 'POST',
291291
headers: {
292292
'content-type': 'application/json',
293-
accept: 'application/graphql+json',
293+
accept: 'application/graphql-response+json',
294294
},
295295
body: JSON.stringify({
296296
query: '{ __typename }',
@@ -350,13 +350,13 @@ describe('Response', () => {
350350
});
351351
});
352352

353-
describe('application/graphql+json', () => {
353+
describe('application/graphql-response+json', () => {
354354
it('must use 4xx or 5xx status codes on JSON parsing failure', async () => {
355355
const res = await fetch(serverUrl, {
356356
method: 'POST',
357357
headers: {
358358
'content-type': 'application/json',
359-
accept: 'application/graphql+json',
359+
accept: 'application/graphql-response+json',
360360
},
361361
body: '{ "not a JSON',
362362
});
@@ -368,7 +368,7 @@ describe('Response', () => {
368368
method: 'POST',
369369
headers: {
370370
'content-type': 'application/json',
371-
accept: 'application/graphql+json',
371+
accept: 'application/graphql-response+json',
372372
},
373373
body: '{ "not a JSON',
374374
});
@@ -380,7 +380,7 @@ describe('Response', () => {
380380
url.searchParams.set('qeury' /* typo */, '{ __typename }');
381381
const res = await fetch(url.toString(), {
382382
method: 'GET',
383-
headers: { accept: 'application/graphql+json' },
383+
headers: { accept: 'application/graphql-response+json' },
384384
});
385385
expect(res.status).toBeGreaterThanOrEqual(400);
386386
expect(res.status).toBeLessThanOrEqual(599);
@@ -390,7 +390,7 @@ describe('Response', () => {
390390
url.searchParams.set('qeury' /* typo */, '{ __typename }');
391391
const res = await fetch(url.toString(), {
392392
method: 'GET',
393-
headers: { accept: 'application/graphql+json' },
393+
headers: { accept: 'application/graphql-response+json' },
394394
});
395395
expect(res.status).toBe(400);
396396
});
@@ -400,7 +400,7 @@ describe('Response', () => {
400400
url.searchParams.set('query', '{');
401401
const res = await fetch(url.toString(), {
402402
method: 'GET',
403-
headers: { accept: 'application/graphql+json' },
403+
headers: { accept: 'application/graphql-response+json' },
404404
});
405405
expect(res.status).toBeGreaterThanOrEqual(400);
406406
expect(res.status).toBeLessThanOrEqual(599);
@@ -410,7 +410,7 @@ describe('Response', () => {
410410
url.searchParams.set('query', '{');
411411
const res = await fetch(url.toString(), {
412412
method: 'GET',
413-
headers: { accept: 'application/graphql+json' },
413+
headers: { accept: 'application/graphql-response+json' },
414414
});
415415
expect(res.status).toBe(400);
416416
});
@@ -420,7 +420,7 @@ describe('Response', () => {
420420
url.searchParams.set('query', '{ 8f31403dfe404bccbb0e835f2629c6a7 }'); // making sure the field doesnt exist
421421
const res = await fetch(url.toString(), {
422422
method: 'GET',
423-
headers: { accept: 'application/graphql+json' },
423+
headers: { accept: 'application/graphql-response+json' },
424424
});
425425
expect(res.status).toBeGreaterThanOrEqual(400);
426426
expect(res.status).toBeLessThanOrEqual(599);
@@ -430,7 +430,7 @@ describe('Response', () => {
430430
url.searchParams.set('query', '{ 8f31403dfe404bccbb0e835f2629c6a7 }'); // making sure the field doesnt exist
431431
const res = await fetch(url.toString(), {
432432
method: 'GET',
433-
headers: { accept: 'application/graphql+json' },
433+
headers: { accept: 'application/graphql-response+json' },
434434
});
435435
expect(res.status).toBe(400);
436436
});

src/client.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ export function createClient(options: ClientOptions): Client {
238238
headers: {
239239
...headers,
240240
'content-type': 'application/json; charset=utf-8',
241-
accept: 'application/graphql+json, application/json',
241+
accept: 'application/graphql-response+json, application/json',
242242
},
243243
credentials,
244244
referrer,
@@ -254,7 +254,7 @@ export function createClient(options: ClientOptions): Client {
254254
const contentType = res.headers.get('content-type');
255255
if (!contentType) throw new Error('Missing response content-type');
256256
if (
257-
!contentType.includes('application/graphql+json') &&
257+
!contentType.includes('application/graphql-response+json') &&
258258
!contentType.includes('application/json')
259259
) {
260260
throw new Error(

src/handler.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ export function createHandler<RawRequest = unknown, Context = unknown>(
369369
statusText: 'Not Acceptable',
370370
headers: {
371371
accept:
372-
'application/graphql+json; charset=utf-8, application/json; charset=utf-8',
372+
'application/graphql-response+json; charset=utf-8, application/json; charset=utf-8',
373373
},
374374
},
375375
];
@@ -570,7 +570,7 @@ export function createHandler<RawRequest = unknown, Context = unknown>(
570570
* @category Server
571571
*/
572572
export type AcceptableMediaType =
573-
| 'application/graphql+json'
573+
| 'application/graphql-response+json'
574574
| 'application/json';
575575

576576
/**
@@ -600,12 +600,12 @@ export function getAcceptableMediaType(
600600
}
601601

602602
if (
603-
(mediaType === 'application/graphql+json' ||
603+
(mediaType === 'application/graphql-response+json' ||
604604
mediaType === 'application/*' ||
605605
mediaType === '*/*') &&
606606
charset === 'charset=utf8'
607607
) {
608-
acceptedMediaType = 'application/graphql+json';
608+
acceptedMediaType = 'application/graphql-response+json';
609609
break;
610610
}
611611
}
@@ -639,7 +639,7 @@ export function makeResponse(
639639
'content-type':
640640
acceptedMediaType === 'application/json'
641641
? 'application/json; charset=utf-8'
642-
: 'application/graphql+json; charset=utf-8',
642+
: 'application/graphql-response+json; charset=utf-8',
643643
},
644644
},
645645
];
@@ -667,7 +667,7 @@ export function makeResponse(
667667
'content-type':
668668
acceptedMediaType === 'application/json'
669669
? 'application/json; charset=utf-8'
670-
: 'application/graphql+json; charset=utf-8',
670+
: 'application/graphql-response+json; charset=utf-8',
671671
},
672672
},
673673
];

0 commit comments

Comments
 (0)