apollographql / apollographql/federation
Error starting @apollo/gateway: Apollo Gateway Failed to Initialize.
- Dominant language
- TypeScript
- Stars
- 727
- Forks
- 276
- Avg merge
- 1h 47m
- Merged PRs (30d)
- 1
Description
```
{"level":"error","time":1667565067554,"pid":15976,"hostname":"MacBook-Pro-6.local","serviceName":"graphql-gateway","app":"backend","esIndex":"graphql-gateway","message":"Apollo Gateway Failed to Initialize. Error: Error: When a manual configuration is not provided, gateway requires an Apollo configuration. See https://www.apollographql.com/docs/apollo-server/federation/managed-federation/ for more information. Manual configuration options include: `serviceList`, `supergraphSdl`, and `experimental_updateServiceDefinitions`."}
{"level":"error","time":1667565067555,"pid":15976,"hostname":"MacBook-Pro-6.local","serviceName":"graphql-gateway","app":"backend","esIndex":"graphql-gateway","message":"Cannot read property 'ApolloServer' of undefined"}
"Cannot read property 'ApolloServer' of undefined"
```
I am getting this error when starting Apollo Gateway. Tried everything and nothing seems to fix the issues. Here is how the server setup looks like:
```
eequire('dotenv').config({ path: './graph-api.env' })
import * as Net from 'net';
import * as Apollo from '@apollo/gateway';
import express from 'express';
import ApolloServer from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import depthLimit from 'graphql-depth-limit';
import https from 'https';
import { readinessProbeStart, livenessProbeStart, blogger } from './server';
import options from '../config/index.js';
import cors from 'cors';
import { json } from 'body-parser';
const port = process.env.PORT || 1688;
const env = process.env.NODE_ENV;
const envIsDevelopment = env === 'development';
class AuthenticatedDataSource extends Apollo.RemoteGraphQLDataSource {
// Make the class accept "name" property
public name!: string;
public constructor(
config?: Partial & Record & ThisType,
) {
super();
if (config) return Object.assign(this, config);
}
// this allows us top map fields from the client request to the internal GraphQL operations
public willSendRequest({ request, context }): void {
const { token, platform } = context && context.credentials;
if (token) request.http.headers.set('authorization', token);
if (platform) request.http.headers.set('platform', platform);
}
// debug logs for getting Federated Tracing up and running...
public didReceiveResponse({ response }): any {
// blogger.log(`Service Response FTV1 Value: ${response.extensions && response.extensions.ftv1}`);
return response;
}
}
/* Returns an instance of ApolloServer with hapi.js middleware. */
const bootstrap = async (): Promise => {
console.log(`APOLLO_KEY ${process.env.APOLLO_KEY}`);
console.log(`APOLLO_GRAPH_REF ${process.env.APOLLO_GRAPH_REF}`);
const app = express();
const httpServer = https.createServer(options.tlsOptions, app);
const gateway = new Apollo.ApolloGateway({
buildService({ name, url }): AuthenticatedDataSource {
return new AuthenticatedDataSource({ name, url });
},
debug: true
});
try {
const loadedSchema = await gateway.load();
} catch (e) {
blogger.error(`Apollo Gateway Failed to Initialize. Error: ${e}`);
}
// Create Apollo Server
const apolloServer = new ApolloServer.ApolloServer({
gateway,
introspection: envIsDevelopment,
validationRules: [depthLimit(6)],
apollo: (() => {
const apiKey = process.env.APOLLO_KEY || process.env.ENGINE_API_KEY;
// const graphVariant = process.env.APOLLO_GRAPH_VARIANT || 'noVariant';
const graphRef = process.env.APOLLO_GRAPH_REF || 'noVariant';
// console.log('APOLLO_GRAPH_VARIANT:', graphVariant);
if (env === 'production' || env === 'production2') return { key: apiKey };
return { key: apiKey, graphRef };
})(),
plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});
await apolloServer.start();
app.use(
'/',
cors({ origin: options.allowedOrigins }),
json(),
expressMiddleware(apolloServer, {
context: async ({ req }) => ({ token: req.headers.token }),
}),
);
httpServer.listen({ port }, (): void => {
blogger.log('🍄 GraphQL Gateway is up and running.');
});
return httpServer;
};
// Handles unhandled promise rejections
process.on('unhandledRejection', (error: Error): never => {
blogger.error(error.message);
throw error;
});
// Start the server and the k8s probes with graceful shutdown in place
bootstrap()
.then((server): void => {
blogger.debug(`GraphQL is running on port ${process.env.PORT}`);
// Graceful Shutdown
process.on(
'SIGTERM',
(): https.Server => {
blogger.debug('SIGTERM event received. Shutting down the server...');
server.close();
return server;
},
);
}) // Liveness and readiness probes
.then((): Net.Server => readinessProbeStart())
.then((): Net.Server => livenessProbeStart())
.catch((error): void => {
blogger.error(error.message);
console.log(JSON.stringify(error.message));
console.log(JSON.stringify(error.locations));
console.log(JSON.stringify(error.extensions));
});
```
Contributor guide
Research direction
Start at the bootstrap entry point shown in the issue, especially the ApolloGateway construction, gateway.load(), and the APOLLO_KEY and APOLLO_GRAPH_REF environment variables. Run the server with the shown configuration and trace initialization until the gateway loads successfully; done means Apollo Gateway initializes and the GraphQL server starts without the reported errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- express, graphql, typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100