forked from ilmimris/apollofederation-keycloak-demo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gateway.js
100 lines (81 loc) · 3.23 KB
/
gateway.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
const { ApolloServer, defaultPlaygroundOptions } = require("apollo-server-express");
const { ApolloGateway, RemoteGraphQLDataSource } = require("@apollo/gateway");
const express = require('express')
const { configureKeycloak } = require('./lib/common');
const { KeycloakContext } = require('keycloak-connect-graphql');
const expressPlayground = require('graphql-playground-middleware-express').default;
const app = express();
const graphqlPath = '/graphql';
const playgroundPath = '/playground';
const gateway = new ApolloGateway({
// This entire `serviceList` is optional when running in managed federation
// mode, using Apollo Graph Manager as the source of truth. In production,
// using a single source of truth to compose a schema is recommended and
// prevents composition failures at runtime using schema validation using
// real usage-based metrics.
serviceList: [
{ name: "accounts", url: "http://localhost:4001/graphql" },
{ name: "reviews", url: "http://localhost:4002/graphql" },
{ name: "products", url: "http://localhost:4003/graphql" },
{ name: "inventory", url: "http://localhost:4004/graphql" }
],
buildService({ name, url }) {
return new RemoteGraphQLDataSource({
url,
willSendRequest({ request, context }) {
// Passing Keycloak Access Token to services
if (context.kauth && context.kauth.accessToken) {
request.http.headers.set('Authorization', 'bearer '+ context.kauth.accessToken.token);
}
}
})
},
// Experimental: Enabling this enables the query plan view in Playground.
__exposeQueryPlanExperimental: false,
});
(async () => {
// perform the standard keycloak-connect middleware setup on our app
const { keycloak } = configureKeycloak(app, graphqlPath);
// Ensure entire GraphQL Api can only be accessed by authenticated users
app.use(playgroundPath, keycloak.protect());
const server = new ApolloServer({
gateway,
// Apollo Graph Manager (previously known as Apollo Engine)
// When enabled and an `ENGINE_API_KEY` is set in the environment,
// provides metrics, schema management and trace reporting.
engine: false,
// Subscriptions are unsupported but planned for a future Gateway version.
subscriptions: false,
// Disable default playground
playground: false,
context: ({ req }) => {
return {
kauth: new KeycloakContext({ req })
}
}
});
// Handle custom GraphQL Playground to use dynamics header token from keycloak
app.get(playgroundPath, (req, res, next) => {
const headers = JSON.stringify({
'X-CSRF-Token': req.kauth.grant.access_token.token,
});
expressPlayground({
...defaultPlaygroundOptions,
endpoint: `${graphqlPath}?headers=${encodeURIComponent(headers)}`,
settings: {
...defaultPlaygroundOptions.settings,
'request.credentials': 'same-origin',
},
version: "",
tabs: ""
})(req, res, next);
});
server.applyMiddleware({ app })
// server.listen().then(({ url }) => {
// console.log(`🚀 Server ready at ${url}`);
// });
const port = 4000;
app.listen({ port },() => {
console.log(`🚀 Server ready at http://localhost:${port}${server.graphqlPath}`);
})
})();