Skip to content

Commit 642cc05

Browse files
authored
Header Propagation E2E Test (#680)
1 parent 63949a2 commit 642cc05

File tree

5 files changed

+184
-1
lines changed

5 files changed

+184
-1
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { defineConfig } from '@graphql-hive/gateway';
2+
3+
export const gatewayConfig = defineConfig({
4+
propagateHeaders: {
5+
fromClientToSubgraphs({ request }) {
6+
return {
7+
authorization: request.headers.get('authorization') ?? 'default',
8+
'session-cookie-id':
9+
request.headers.get('session-cookie-id') ?? 'default',
10+
};
11+
},
12+
},
13+
});
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { createTenv } from '@internal/e2e';
2+
import { expect, it } from 'vitest';
3+
4+
const { gateway, service } = createTenv(__dirname);
5+
6+
it('propagates headers to subgraphs', async () => {
7+
await using gw = await gateway({
8+
supergraph: {
9+
with: 'apollo',
10+
services: [await service('upstream')],
11+
},
12+
});
13+
const result = await gw.execute({
14+
query: /* GraphQL */ `
15+
query {
16+
headers {
17+
authorization
18+
sessionCookieId
19+
}
20+
}
21+
`,
22+
headers: {
23+
authorization: 'Bearer token',
24+
'session-cookie-id': 'session-cookie',
25+
},
26+
});
27+
expect(result).toEqual({
28+
data: {
29+
headers: {
30+
authorization: 'Bearer token',
31+
sessionCookieId: 'session-cookie',
32+
},
33+
},
34+
});
35+
});
36+
37+
it('sends default headers to subgraphs', async () => {
38+
await using gw = await gateway({
39+
supergraph: {
40+
with: 'apollo',
41+
services: [await service('upstream')],
42+
},
43+
});
44+
const result = await gw.execute({
45+
query: /* GraphQL */ `
46+
query {
47+
headers {
48+
authorization
49+
sessionCookieId
50+
}
51+
}
52+
`,
53+
});
54+
expect(result).toEqual({
55+
data: {
56+
headers: {
57+
authorization: 'default',
58+
sessionCookieId: 'default',
59+
},
60+
},
61+
});
62+
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "@e2e/header-propagation",
3+
"private": true,
4+
"dependencies": {
5+
"graphql": "^16.9.0",
6+
"tslib": "^2.8.1"
7+
},
8+
"devDependencies": {
9+
"@apollo/server": "^4.10.3",
10+
"@apollo/subgraph": "^2.7.2",
11+
"@types/cors": "^2.8.17",
12+
"@types/express": "^5.0.0",
13+
"cors": "^2.8.5",
14+
"express": "^4.21.2"
15+
}
16+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { ApolloServer } from '@apollo/server';
2+
import {
3+
ExpressContextFunctionArgument,
4+
expressMiddleware,
5+
} from '@apollo/server/express4';
6+
import { buildSubgraphSchema } from '@apollo/subgraph';
7+
import { GraphQLResolverMap } from '@apollo/subgraph/dist/schema-helper';
8+
import { Opts } from '@internal/testing';
9+
import cors from 'cors';
10+
import express from 'express';
11+
import { parse } from 'graphql';
12+
13+
const app = express();
14+
15+
const resolvers: GraphQLResolverMap<ExpressContextFunctionArgument> = {
16+
Query: {
17+
headers: (_source, _args, context) => {
18+
return {
19+
authorization: context.req.headers.authorization,
20+
sessionCookieId: context.req.headers['session-cookie-id'],
21+
};
22+
},
23+
},
24+
};
25+
26+
const server = new ApolloServer<ExpressContextFunctionArgument>({
27+
schema: buildSubgraphSchema({
28+
typeDefs: parse(/* GraphQL */ `
29+
type Query {
30+
headers: Headers!
31+
}
32+
33+
type Headers {
34+
authorization: String!
35+
sessionCookieId: String!
36+
}
37+
`),
38+
resolvers: resolvers as GraphQLResolverMap<unknown>,
39+
}),
40+
});
41+
42+
async function main() {
43+
// Note you must call `start()` on the `ApolloServer`
44+
// instance before passing the instance to `expressMiddleware`
45+
await server.start();
46+
47+
// Specify the path where we'd like to mount our server
48+
app.use(
49+
'/graphql',
50+
cors(),
51+
express.json(),
52+
// @ts-expect-error - Weird typing issue with `expressMiddleware`
53+
expressMiddleware(server, { context: (ctx) => ctx }),
54+
);
55+
56+
const opts = Opts(process.argv);
57+
58+
app.listen(opts.getServicePort('upstream'), () => {
59+
console.log(
60+
`🚀 Server ready at http://localhost:${opts.getServicePort('upstream')}/graphql`,
61+
);
62+
});
63+
}
64+
65+
main().catch((e) => {
66+
console.error(e);
67+
process.exit(1);
68+
});

yarn.lock

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2520,6 +2520,21 @@ __metadata:
25202520
languageName: unknown
25212521
linkType: soft
25222522

2523+
"@e2e/header-propagation@workspace:e2e/header-propagation":
2524+
version: 0.0.0-use.local
2525+
resolution: "@e2e/header-propagation@workspace:e2e/header-propagation"
2526+
dependencies:
2527+
"@apollo/server": "npm:^4.10.3"
2528+
"@apollo/subgraph": "npm:^2.7.2"
2529+
"@types/cors": "npm:^2.8.17"
2530+
"@types/express": "npm:^5.0.0"
2531+
cors: "npm:^2.8.5"
2532+
express: "npm:^4.21.2"
2533+
graphql: "npm:^16.9.0"
2534+
tslib: "npm:^2.8.1"
2535+
languageName: unknown
2536+
linkType: soft
2537+
25232538
"@e2e/hmac-auth-https@workspace:e2e/hmac-auth-https":
25242539
version: 0.0.0-use.local
25252540
resolution: "@e2e/hmac-auth-https@workspace:e2e/hmac-auth-https"
@@ -6707,6 +6722,15 @@ __metadata:
67076722
languageName: node
67086723
linkType: hard
67096724

6725+
"@types/cors@npm:^2.8.17":
6726+
version: 2.8.17
6727+
resolution: "@types/cors@npm:2.8.17"
6728+
dependencies:
6729+
"@types/node": "npm:*"
6730+
checksum: 10c0/457364c28c89f3d9ed34800e1de5c6eaaf344d1bb39af122f013322a50bc606eb2aa6f63de4e41a7a08ba7ef454473926c94a830636723da45bf786df032696d
6731+
languageName: node
6732+
linkType: hard
6733+
67106734
"@types/docker-modem@npm:*":
67116735
version: 3.0.6
67126736
resolution: "@types/docker-modem@npm:3.0.6"
@@ -10681,7 +10705,7 @@ __metadata:
1068110705
languageName: node
1068210706
linkType: hard
1068310707

10684-
"express@npm:^4.21.1":
10708+
"express@npm:^4.21.1, express@npm:^4.21.2":
1068510709
version: 4.21.2
1068610710
resolution: "express@npm:4.21.2"
1068710711
dependencies:

0 commit comments

Comments
 (0)