hot reload apollo gateway

it’s not unusual that there are cases we have new graphql servers to be added, or existing graphql servers updated.

Apollo server at the moment, have a gateway component which could statically maintain and route the right traffic to the right server and aggregate results.

However, this community version of Apollo server and gateway is not able to cater for the case in the beginning, where we would like to hot update/reload the gateway with any updates however with shut down the servers.

After some trials and errors, this is the work around to sort this out:

instead of hardcode the service list (apollo graphql servers), maintain it separately and dynamically:

#### instead of this
const gateway = new ApolloGateway({
  serviceList: [
    { name: "astronauts", url: "http://localhost:4002" },
    { name: "missions", url: "http://localhost:4003" }
  ]
});

## maintain this list
#### instead of this
const dynamicServiceList = [
    { name: "astronauts", url: "http://localhost:4002" },
    { name: "missions", url: "http://localhost:4003" }
  ];

then from apollo gateway, instead of spoon feeding the list, switch it to dynamically load the definitions

const gateway = new ApolloGateway({
  serviceList: [],
...
  experimental_updateServiceDefinitions: async (serviceList) => {
    return {
      isNewSchema: true,
      serviceDefinitions:  await Promise.all(dynamicServiceList.map(async (service) => {
//load the sql
        const data =  await request(service.url, sdlGQL);
...
        return {
...
//then feed the data here
          name: service.name,
          url: service.url,
          typeDefs: parse(data._service.sdl)
        };
      }))
    };
  }
});

At the same time, create a new endpoint, if needed, to take in updated servers, or new servers, so that to update the dynamic list

app.get('/hot_reload_schema/', async (req, res) => {
//get the new server info from req
....
      const status = await validateSDL(name, url);
      if (status){
//update the dynamic list
        dynamicServiceList.push({name, url});
        res.send('The new schema has been successfully registered');
      }
      else {
        res.send('Please check the log for the error details while registering this schema');
      }
    }
);

lastly, make sure the gateway is polling the service list at some intervals:

new ApolloGateway({
  pollingTimer: 100_000,
  experimental_pollInterval: 100_000,
....
});

alternatively, this could also be updated by an explicit load:

new ApolloGateway({
....
}).load();

have contributed the solution to the community here.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s