pepijno
pepijno

Reputation: 246

How to start apollo federation server only when all services are available

I want to start a federated apollo server:

const gateway = new ApolloGateway({
  serviceList: [
    ... list of services
  ],
});

const startServer = async () => {
  const gatewayConfig = await gateway.load();
  const server = new ApolloServer({
    ...gatewayConfig,
    subscriptions: false,
  });

  server.listen().then(({ url }) => {
    console.log("Server running!");
  });
};

startServer();

When I start the server and one of the services in the serviceList is available, the server starts and logs which services have failed. I want the server to only start when all the services are available, ie when one service is unavailable an error is thrown and the server stops. Any ideas how to do this?

Upvotes: 2

Views: 1323

Answers (1)

Rockettomatoo
Rockettomatoo

Reputation: 277

Apollo can't do this as of writing this answer. The only solution is to monitor the availability manually and leverage apollo accordingly. I used apollo-server-express for this.

Below is a demonstration of how I managed to leverage my apollo gateway based on the availability of my services.
Basically, you wrap the middleware of your apollo server. This allows you to exchange your apollo server instance as well as throwing an error when they are not available.

import express from 'express';
import { ApolloServer } from 'apollo-server-express';
import bodyParser from 'body-parser'; // use express body-parser for convinience

// your list of federated services
const serviceList = [
 { name: 'service1', url: 'http://service1/graphql' }
];

// a variable to store the server. We will need to replace him when a service goes offline or comes back online again
let server = null;

// setup express
const app = express();
app.use(bodyParser.json());
app.use(customRouterToLeverageApolloServer); // defined below

// middleware to leverage apollo server
function customRouterToLeverageApolloServer(req, res, next) {
  // if services are down (no apollo instance) throw an error
  if(!server) {
    res.json({ error: 'services are currently not available' });
    return;
  }

  // else pass the request to apollo
  const router = server.getMiddleware(); // https://www.apollographql.com/docs/apollo-server/api/apollo-server/#apolloservergetmiddleware
  return router(req, res, next);
}

function servicesAreAvailable() {
  // go through your serviceList and check availability
}

// periodically check the availability of your services and create/destroy an ApolloServer instance accordingly. This will also be the indication whether or not your services are available at the time.
// you might want to also call this function at startup
setInterval(() => {
  if(servicesAreAvailable()) {
    server = new ApolloServer({ ... });
  }
  else {
    server = null;
  }
}, 1000 * 60 * 5) // check every 5 minutes

Upvotes: 1

Related Questions